nvidia-nat 1.2.0rc5__py3-none-any.whl → 1.2.0rc6__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 → nat}/agent/react_agent/agent.py +12 -12
- {aiq → nat}/agent/react_agent/register.py +20 -20
- {aiq → nat}/agent/reasoning_agent/reasoning_agent.py +14 -14
- {aiq → nat}/agent/rewoo_agent/agent.py +7 -7
- {aiq → nat}/agent/rewoo_agent/prompt.py +11 -12
- {aiq → nat}/agent/rewoo_agent/register.py +47 -49
- {aiq → nat}/agent/tool_calling_agent/agent.py +4 -4
- {aiq → nat}/agent/tool_calling_agent/register.py +8 -8
- {aiq → nat}/authentication/api_key/api_key_auth_provider.py +6 -6
- {aiq → nat}/authentication/api_key/api_key_auth_provider_config.py +5 -5
- {aiq → nat}/authentication/api_key/register.py +4 -4
- {aiq → nat}/authentication/http_basic_auth/http_basic_auth_provider.py +10 -10
- {aiq → nat}/authentication/http_basic_auth/register.py +4 -4
- {aiq → nat}/authentication/interfaces.py +6 -6
- {aiq → nat}/authentication/oauth2/oauth2_auth_code_flow_provider.py +11 -11
- {aiq → nat}/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +1 -1
- {aiq → nat}/authentication/oauth2/register.py +4 -4
- {aiq → nat}/authentication/register.py +3 -3
- {aiq → nat}/builder/builder.py +30 -30
- {aiq → nat}/builder/component_utils.py +23 -23
- {aiq → nat}/builder/context.py +35 -29
- {aiq → nat}/builder/embedder.py +1 -1
- {aiq → nat}/builder/eval_builder.py +13 -13
- {aiq → nat}/builder/evaluator.py +3 -3
- {aiq → nat}/builder/front_end.py +11 -11
- {aiq → nat}/builder/function.py +8 -8
- {aiq → nat}/builder/function_base.py +6 -6
- {aiq → nat}/builder/function_info.py +3 -3
- {aiq → nat}/builder/intermediate_step_manager.py +13 -13
- {aiq → nat}/builder/llm.py +1 -1
- {aiq → nat}/builder/retriever.py +1 -1
- {aiq → nat}/builder/user_interaction_manager.py +14 -10
- {aiq → nat}/builder/workflow.py +25 -25
- {aiq → nat}/builder/workflow_builder.py +86 -86
- {aiq → nat}/cli/cli_utils/config_override.py +2 -2
- {aiq → nat}/cli/cli_utils/validation.py +4 -4
- {aiq → nat}/cli/commands/configure/channel/add.py +2 -2
- {aiq → nat}/cli/commands/configure/channel/channel.py +4 -6
- {aiq → nat}/cli/commands/configure/channel/remove.py +2 -2
- {aiq → nat}/cli/commands/configure/channel/update.py +2 -2
- {aiq → nat}/cli/commands/configure/configure.py +3 -3
- {aiq → nat}/cli/commands/evaluate.py +3 -3
- {aiq → nat}/cli/commands/info/info.py +5 -7
- {aiq → nat}/cli/commands/info/list_channels.py +1 -1
- {aiq → nat}/cli/commands/info/list_components.py +14 -14
- {aiq → nat}/cli/commands/info/list_mcp.py +106 -15
- {aiq → nat}/cli/commands/registry/publish.py +9 -9
- {aiq → nat}/cli/commands/registry/pull.py +10 -10
- {aiq → nat}/cli/commands/registry/registry.py +5 -7
- {aiq → nat}/cli/commands/registry/remove.py +8 -8
- {aiq → nat}/cli/commands/registry/search.py +15 -15
- {aiq → nat}/cli/commands/sizing/calc.py +3 -3
- {aiq → nat}/cli/commands/start.py +15 -15
- {aiq → nat}/cli/commands/uninstall.py +5 -5
- {aiq → nat}/cli/commands/validate.py +1 -1
- {aiq → nat}/cli/commands/workflow/templates/pyproject.toml.j2 +4 -4
- {aiq → nat}/cli/commands/workflow/templates/workflow.py.j2 +4 -4
- {aiq → nat}/cli/commands/workflow/workflow.py +3 -3
- {aiq → nat}/cli/commands/workflow/workflow_commands.py +15 -11
- {aiq → nat}/cli/entrypoint.py +6 -6
- {aiq → nat}/cli/main.py +15 -2
- {aiq → nat}/cli/register_workflow.py +70 -70
- {aiq → nat}/cli/type_registry.py +82 -82
- {aiq → nat}/data_models/api_server.py +121 -99
- {aiq → nat}/data_models/authentication.py +2 -2
- {aiq → nat}/data_models/component.py +5 -1
- {aiq → nat}/data_models/component_ref.py +12 -12
- {aiq → nat}/data_models/config.py +17 -13
- {aiq → nat}/data_models/dataset_handler.py +58 -12
- {aiq → nat}/data_models/discovery_metadata.py +36 -66
- {aiq → nat}/data_models/evaluate.py +9 -9
- {aiq → nat}/data_models/intermediate_step.py +7 -7
- {aiq → nat}/data_models/retriever.py +2 -2
- {aiq → nat}/data_models/span.py +10 -7
- {aiq → nat}/data_models/step_adaptor.py +1 -1
- {aiq → nat}/data_models/telemetry_exporter.py +2 -2
- {aiq → nat}/embedder/nim_embedder.py +5 -5
- {aiq → nat}/embedder/openai_embedder.py +5 -5
- {aiq/retriever → nat/embedder}/register.py +2 -2
- {aiq → nat}/eval/config.py +4 -4
- {aiq → nat}/eval/dataset_handler/dataset_downloader.py +1 -1
- {aiq → nat}/eval/dataset_handler/dataset_filter.py +1 -1
- {aiq → nat}/eval/dataset_handler/dataset_handler.py +127 -14
- {aiq → nat}/eval/evaluate.py +38 -34
- {aiq → nat}/eval/evaluator/base_evaluator.py +9 -5
- {aiq → nat}/eval/evaluator/evaluator_model.py +4 -4
- {aiq → nat}/eval/intermediate_step_adapter.py +2 -2
- {aiq → nat}/eval/rag_evaluator/evaluate.py +8 -8
- {aiq → nat}/eval/rag_evaluator/register.py +7 -7
- {aiq → nat}/eval/remote_workflow.py +8 -8
- {aiq → nat}/eval/runners/config.py +2 -2
- {aiq → nat}/eval/runners/multi_eval_runner.py +4 -4
- {aiq → nat}/eval/runtime_event_subscriber.py +3 -3
- {aiq → nat}/eval/swe_bench_evaluator/evaluate.py +6 -6
- {aiq → nat}/eval/swe_bench_evaluator/register.py +4 -4
- {aiq → nat}/eval/trajectory_evaluator/evaluate.py +5 -5
- {aiq → nat}/eval/trajectory_evaluator/register.py +5 -5
- {aiq → nat}/eval/tunable_rag_evaluator/evaluate.py +3 -3
- {aiq → nat}/eval/tunable_rag_evaluator/register.py +6 -6
- {aiq → nat}/eval/utils/output_uploader.py +1 -1
- {aiq → nat}/eval/utils/weave_eval.py +6 -6
- {aiq → nat}/experimental/decorators/experimental_warning_decorator.py +6 -2
- {aiq → nat}/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +10 -10
- {aiq → nat}/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +10 -10
- {aiq → nat}/experimental/test_time_compute/editing/motivation_aware_summarization.py +10 -10
- {aiq → nat}/experimental/test_time_compute/functions/execute_score_select_function.py +10 -10
- {aiq → nat}/experimental/test_time_compute/functions/plan_select_execute_function.py +17 -17
- aiq/experimental/test_time_compute/functions/its_tool_orchestration_function.py → nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +12 -12
- aiq/experimental/test_time_compute/functions/its_tool_wrapper_function.py → nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +10 -10
- {aiq → nat}/experimental/test_time_compute/models/editor_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/scoring_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/search_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/selection_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/strategy_base.py +4 -4
- {aiq → nat}/experimental/test_time_compute/register.py +2 -2
- {aiq → nat}/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +11 -11
- {aiq → nat}/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +11 -11
- {aiq → nat}/experimental/test_time_compute/scoring/motivation_aware_scorer.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/multi_llm_planner.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/multi_query_retrieval_search.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/best_of_n_selector.py +7 -7
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_plan_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/threshold_selector.py +7 -7
- {aiq → nat}/front_ends/console/authentication_flow_handler.py +6 -6
- {aiq → nat}/front_ends/console/console_front_end_config.py +2 -2
- {aiq → nat}/front_ends/console/console_front_end_plugin.py +9 -9
- {aiq → nat}/front_ends/console/register.py +5 -5
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +4 -4
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +6 -6
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_config.py +22 -15
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_plugin.py +10 -10
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_plugin_worker.py +110 -115
- {aiq → nat}/front_ends/fastapi/intermediate_steps_subscriber.py +10 -10
- {aiq → nat}/front_ends/fastapi/main.py +8 -8
- {aiq → nat}/front_ends/fastapi/message_handler.py +58 -36
- {aiq → nat}/front_ends/fastapi/message_validator.py +55 -48
- {aiq → nat}/front_ends/fastapi/register.py +5 -5
- {aiq → nat}/front_ends/fastapi/response_helpers.py +26 -26
- {aiq → nat}/front_ends/fastapi/step_adaptor.py +35 -37
- {aiq → nat}/front_ends/mcp/mcp_front_end_config.py +12 -8
- nat/front_ends/mcp/mcp_front_end_plugin.py +81 -0
- nat/front_ends/mcp/mcp_front_end_plugin_worker.py +143 -0
- {aiq → nat}/front_ends/mcp/register.py +5 -5
- {aiq → nat}/front_ends/mcp/tool_converter.py +20 -21
- {aiq → nat}/front_ends/simple_base/simple_front_end_plugin_base.py +6 -6
- {aiq → nat}/llm/aws_bedrock_llm.py +5 -5
- {aiq → nat}/llm/nim_llm.py +5 -5
- {aiq → nat}/llm/openai_llm.py +5 -5
- {aiq → nat}/memory/__init__.py +2 -2
- nat/meta/pypi.md +58 -0
- {aiq → nat}/object_store/__init__.py +2 -2
- {aiq → nat}/object_store/in_memory_object_store.py +6 -6
- {aiq → nat}/observability/exporter/base_exporter.py +9 -9
- {aiq → nat}/observability/exporter/exporter.py +1 -1
- {aiq → nat}/observability/exporter/file_exporter.py +6 -6
- {aiq → nat}/observability/exporter/processing_exporter.py +9 -9
- {aiq → nat}/observability/exporter/raw_exporter.py +4 -4
- {aiq → nat}/observability/exporter/span_exporter.py +57 -34
- {aiq → nat}/observability/exporter_manager.py +6 -6
- {aiq → nat}/observability/mixin/file_mixin.py +2 -2
- {aiq → nat}/observability/processor/batching_processor.py +1 -1
- {aiq → nat}/observability/processor/callback_processor.py +1 -1
- {aiq → nat}/observability/processor/intermediate_step_serializer.py +4 -4
- {aiq → nat}/observability/processor/processor.py +1 -1
- {aiq → nat}/observability/register.py +7 -7
- {aiq → nat}/profiler/calc/calc_runner.py +18 -18
- {aiq → nat}/profiler/calc/calculations.py +3 -3
- {aiq → nat}/profiler/calc/plot.py +2 -2
- {aiq → nat}/profiler/callbacks/agno_callback_handler.py +14 -14
- {aiq → nat}/profiler/callbacks/langchain_callback_handler.py +11 -11
- {aiq → nat}/profiler/callbacks/llama_index_callback_handler.py +12 -12
- {aiq → nat}/profiler/callbacks/semantic_kernel_callback_handler.py +11 -11
- {aiq → nat}/profiler/data_models.py +2 -2
- {aiq → nat}/profiler/decorators/framework_wrapper.py +6 -6
- {aiq → nat}/profiler/decorators/function_tracking.py +10 -10
- {aiq → nat}/profiler/forecasting/model_trainer.py +5 -5
- {aiq → nat}/profiler/forecasting/models/linear_model.py +5 -4
- {aiq → nat}/profiler/forecasting/models/random_forest_regressor.py +5 -4
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +7 -7
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +4 -4
- {aiq → nat}/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +6 -6
- {aiq → nat}/profiler/inference_optimization/experimental/prefix_span_analysis.py +6 -6
- {aiq → nat}/profiler/inference_optimization/llm_metrics.py +2 -2
- {aiq → nat}/profiler/inference_optimization/prompt_caching.py +5 -5
- {aiq → nat}/profiler/inference_optimization/token_uniqueness.py +4 -4
- {aiq → nat}/profiler/inference_optimization/workflow_runtimes.py +3 -3
- {aiq → nat}/profiler/intermediate_property_adapter.py +3 -3
- {aiq → nat}/profiler/profile_runner.py +17 -17
- {aiq → nat}/profiler/utils.py +4 -4
- {aiq → nat}/registry_handlers/local/local_handler.py +19 -19
- {aiq → nat}/registry_handlers/local/register_local.py +4 -4
- {aiq → nat}/registry_handlers/metadata_factory.py +7 -7
- {aiq → nat}/registry_handlers/package_utils.py +37 -33
- {aiq → nat}/registry_handlers/pypi/pypi_handler.py +21 -21
- {aiq → nat}/registry_handlers/pypi/register_pypi.py +6 -6
- {aiq → nat}/registry_handlers/registry_handler_base.py +21 -21
- {aiq → nat}/registry_handlers/rest/register_rest.py +7 -7
- {aiq → nat}/registry_handlers/rest/rest_handler.py +19 -19
- {aiq → nat}/registry_handlers/schemas/package.py +3 -3
- {aiq → nat}/registry_handlers/schemas/publish.py +17 -12
- {aiq → nat}/registry_handlers/schemas/pull.py +6 -6
- {aiq → nat}/registry_handlers/schemas/remove.py +2 -2
- {aiq → nat}/registry_handlers/schemas/search.py +11 -11
- {aiq → nat}/retriever/interface.py +6 -2
- {aiq → nat}/retriever/milvus/register.py +7 -7
- {aiq → nat}/retriever/milvus/retriever.py +8 -8
- {aiq → nat}/retriever/models.py +10 -7
- {aiq → nat}/retriever/nemo_retriever/register.py +6 -6
- {aiq → nat}/retriever/nemo_retriever/retriever.py +10 -10
- {aiq/embedder → nat/retriever}/register.py +2 -4
- {aiq → nat}/runtime/loader.py +38 -33
- {aiq → nat}/runtime/runner.py +30 -25
- {aiq → nat}/runtime/session.py +19 -15
- {aiq → nat}/runtime/user_metadata.py +1 -1
- {aiq → nat}/settings/global_settings.py +11 -11
- {aiq → nat}/tool/chat_completion.py +6 -6
- {aiq → nat}/tool/code_execution/README.md +2 -2
- {aiq → nat}/tool/code_execution/code_sandbox.py +1 -1
- {aiq → nat}/tool/code_execution/register.py +5 -5
- {aiq → nat}/tool/code_execution/test_code_execution_sandbox.py +1 -1
- {aiq → nat}/tool/datetime_tools.py +4 -4
- {aiq → nat}/tool/document_search.py +6 -6
- {aiq → nat}/tool/github_tools/create_github_commit.py +4 -4
- {aiq → nat}/tool/github_tools/create_github_issue.py +4 -4
- {aiq → nat}/tool/github_tools/create_github_pr.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_file.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_issue.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_pr.py +4 -4
- {aiq → nat}/tool/github_tools/update_github_issue.py +4 -4
- {aiq → nat}/tool/mcp/exceptions.py +1 -1
- {aiq → nat}/tool/mcp/mcp_client.py +2 -2
- {aiq → nat}/tool/mcp/mcp_tool.py +7 -7
- {aiq → nat}/tool/memory_tools/add_memory_tool.py +6 -6
- {aiq → nat}/tool/memory_tools/delete_memory_tool.py +6 -6
- {aiq → nat}/tool/memory_tools/get_memory_tool.py +6 -6
- {aiq → nat}/tool/nvidia_rag.py +4 -4
- {aiq → nat}/tool/retriever.py +20 -15
- {aiq → nat}/tool/server_tools.py +16 -16
- {aiq → nat}/utils/dump_distro_mapping.py +2 -2
- {aiq → nat}/utils/exception_handlers/mcp.py +8 -8
- {aiq → nat}/utils/io/yaml_tools.py +1 -1
- {aiq → nat}/utils/metadata_utils.py +2 -2
- {aiq → nat}/utils/reactive/base/observable_base.py +2 -2
- {aiq → nat}/utils/reactive/base/subject_base.py +1 -1
- {aiq → nat}/utils/reactive/observable.py +5 -5
- {aiq → nat}/utils/reactive/observer.py +1 -1
- {aiq → nat}/utils/reactive/subject.py +4 -4
- {aiq → nat}/utils/reactive/subscription.py +1 -1
- {aiq → nat}/utils/settings/global_settings.py +4 -4
- {aiq → nat}/utils/type_converter.py +1 -1
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc6.dist-info}/METADATA +37 -37
- nvidia_nat-1.2.0rc6.dist-info/RECORD +434 -0
- nvidia_nat-1.2.0rc6.dist-info/entry_points.txt +21 -0
- nvidia_nat-1.2.0rc6.dist-info/top_level.txt +1 -0
- aiq/embedder/langchain_client.py +0 -41
- aiq/front_ends/mcp/mcp_front_end_plugin.py +0 -93
- aiq/meta/module_to_distro.json +0 -3
- aiq/meta/pypi.md +0 -58
- nvidia_nat-1.2.0rc5.dist-info/RECORD +0 -435
- nvidia_nat-1.2.0rc5.dist-info/entry_points.txt +0 -20
- nvidia_nat-1.2.0rc5.dist-info/top_level.txt +0 -1
- {aiq → nat}/agent/__init__.py +0 -0
- {aiq → nat}/agent/base.py +0 -0
- {aiq → nat}/agent/dual_node.py +0 -0
- {aiq → nat}/agent/react_agent/__init__.py +0 -0
- {aiq → nat}/agent/react_agent/output_parser.py +0 -0
- {aiq → nat}/agent/react_agent/prompt.py +0 -0
- {aiq → nat}/agent/reasoning_agent/__init__.py +0 -0
- {aiq → nat}/agent/register.py +0 -0
- {aiq → nat}/agent/rewoo_agent/__init__.py +0 -0
- {aiq → nat}/agent/tool_calling_agent/__init__.py +0 -0
- {aiq → nat}/authentication/__init__.py +0 -0
- {aiq → nat}/authentication/api_key/__init__.py +0 -0
- {aiq → nat}/authentication/exceptions/__init__.py +0 -0
- {aiq → nat}/authentication/exceptions/api_key_exceptions.py +0 -0
- {aiq → nat}/authentication/http_basic_auth/__init__.py +0 -0
- {aiq → nat}/authentication/oauth2/__init__.py +0 -0
- {aiq → nat}/builder/__init__.py +0 -0
- {aiq → nat}/builder/framework_enum.py +0 -0
- {aiq → nat}/cli/__init__.py +0 -0
- {aiq → nat}/cli/cli_utils/__init__.py +0 -0
- {aiq → nat}/cli/commands/__init__.py +0 -0
- {aiq → nat}/cli/commands/configure/__init__.py +0 -0
- {aiq → nat}/cli/commands/configure/channel/__init__.py +0 -0
- {aiq → nat}/cli/commands/info/__init__.py +0 -0
- {aiq → nat}/cli/commands/registry/__init__.py +0 -0
- {aiq → nat}/cli/commands/sizing/__init__.py +0 -0
- {aiq → nat}/cli/commands/sizing/sizing.py +0 -0
- {aiq → nat}/cli/commands/workflow/__init__.py +0 -0
- {aiq → nat}/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- {aiq → nat}/cli/commands/workflow/templates/config.yml.j2 +0 -0
- {aiq → nat}/cli/commands/workflow/templates/register.py.j2 +0 -0
- {aiq → nat}/data_models/__init__.py +0 -0
- {aiq → nat}/data_models/common.py +0 -0
- {aiq → nat}/data_models/embedder.py +0 -0
- {aiq → nat}/data_models/evaluator.py +0 -0
- {aiq → nat}/data_models/front_end.py +0 -0
- {aiq → nat}/data_models/function.py +0 -0
- {aiq → nat}/data_models/function_dependencies.py +0 -0
- {aiq → nat}/data_models/interactive.py +0 -0
- {aiq → nat}/data_models/invocation_node.py +0 -0
- {aiq → nat}/data_models/llm.py +0 -0
- {aiq → nat}/data_models/logging.py +0 -0
- {aiq → nat}/data_models/memory.py +0 -0
- {aiq → nat}/data_models/object_store.py +0 -0
- {aiq → nat}/data_models/profiler.py +0 -0
- {aiq → nat}/data_models/registry_handler.py +0 -0
- {aiq → nat}/data_models/retry_mixin.py +0 -0
- {aiq → nat}/data_models/streaming.py +0 -0
- {aiq → nat}/data_models/swe_bench_model.py +0 -0
- {aiq → nat}/data_models/ttc_strategy.py +0 -0
- {aiq → nat}/embedder/__init__.py +0 -0
- {aiq → nat}/eval/__init__.py +0 -0
- {aiq → nat}/eval/dataset_handler/__init__.py +0 -0
- {aiq → nat}/eval/evaluator/__init__.py +0 -0
- {aiq → nat}/eval/rag_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/register.py +0 -0
- {aiq → nat}/eval/runners/__init__.py +0 -0
- {aiq → nat}/eval/swe_bench_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/trajectory_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/tunable_rag_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/usage_stats.py +0 -0
- {aiq → nat}/eval/utils/__init__.py +0 -0
- {aiq → nat}/eval/utils/tqdm_position_registry.py +0 -0
- {aiq → nat}/experimental/__init__.py +0 -0
- {aiq → nat}/experimental/decorators/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/editing/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/functions/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/stage_enums.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/tool_use_config.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/ttc_item.py +0 -0
- {aiq → nat}/experimental/test_time_compute/scoring/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/search/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/selection/__init__.py +0 -0
- {aiq → nat}/front_ends/__init__.py +0 -0
- {aiq → nat}/front_ends/console/__init__.py +0 -0
- {aiq → nat}/front_ends/cron/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_controller.py +0 -0
- {aiq → nat}/front_ends/fastapi/html_snippets/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/html_snippets/auth_code_grant_success.py +0 -0
- {aiq → nat}/front_ends/fastapi/job_store.py +0 -0
- {aiq → nat}/front_ends/mcp/__init__.py +0 -0
- {aiq → nat}/front_ends/register.py +0 -0
- {aiq → nat}/front_ends/simple_base/__init__.py +0 -0
- {aiq → nat}/llm/__init__.py +0 -0
- {aiq → nat}/llm/register.py +0 -0
- {aiq → nat}/llm/utils/__init__.py +0 -0
- {aiq → nat}/llm/utils/env_config_value.py +0 -0
- {aiq → nat}/llm/utils/error.py +0 -0
- {aiq → nat}/memory/interfaces.py +0 -0
- {aiq → nat}/memory/models.py +0 -0
- {aiq → nat}/object_store/interfaces.py +0 -0
- {aiq → nat}/object_store/models.py +0 -0
- {aiq → nat}/object_store/register.py +0 -0
- {aiq → nat}/observability/__init__.py +0 -0
- {aiq → nat}/observability/exporter/__init__.py +0 -0
- {aiq → nat}/observability/mixin/__init__.py +0 -0
- {aiq → nat}/observability/mixin/batch_config_mixin.py +0 -0
- {aiq → nat}/observability/mixin/collector_config_mixin.py +0 -0
- {aiq → nat}/observability/mixin/file_mode.py +0 -0
- {aiq → nat}/observability/mixin/resource_conflict_mixin.py +0 -0
- {aiq → nat}/observability/mixin/serialize_mixin.py +0 -0
- {aiq → nat}/observability/mixin/type_introspection_mixin.py +0 -0
- {aiq → nat}/observability/processor/__init__.py +0 -0
- {aiq → nat}/observability/utils/__init__.py +0 -0
- {aiq → nat}/observability/utils/dict_utils.py +0 -0
- {aiq → nat}/observability/utils/time_utils.py +0 -0
- {aiq → nat}/plugins/.namespace +0 -0
- {aiq → nat}/profiler/__init__.py +0 -0
- {aiq → nat}/profiler/calc/__init__.py +0 -0
- {aiq → nat}/profiler/calc/data_models.py +0 -0
- {aiq → nat}/profiler/callbacks/__init__.py +0 -0
- {aiq → nat}/profiler/callbacks/base_callback_class.py +0 -0
- {aiq → nat}/profiler/callbacks/token_usage_base_model.py +0 -0
- {aiq → nat}/profiler/data_frame_row.py +0 -0
- {aiq → nat}/profiler/decorators/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/config.py +0 -0
- {aiq → nat}/profiler/forecasting/models/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/models/forecasting_base_model.py +0 -0
- {aiq → nat}/profiler/inference_metrics_model.py +0 -0
- {aiq → nat}/profiler/inference_optimization/__init__.py +0 -0
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- {aiq → nat}/profiler/inference_optimization/data_models.py +0 -0
- {aiq → nat}/profiler/inference_optimization/experimental/__init__.py +0 -0
- {aiq → nat}/registry_handlers/__init__.py +0 -0
- {aiq → nat}/registry_handlers/local/__init__.py +0 -0
- {aiq → nat}/registry_handlers/pypi/__init__.py +0 -0
- {aiq → nat}/registry_handlers/register.py +0 -0
- {aiq → nat}/registry_handlers/rest/__init__.py +0 -0
- {aiq → nat}/registry_handlers/schemas/__init__.py +0 -0
- {aiq → nat}/registry_handlers/schemas/headers.py +0 -0
- {aiq → nat}/registry_handlers/schemas/status.py +0 -0
- {aiq → nat}/retriever/__init__.py +0 -0
- {aiq → nat}/retriever/milvus/__init__.py +0 -0
- {aiq → nat}/retriever/nemo_retriever/__init__.py +0 -0
- {aiq → nat}/runtime/__init__.py +0 -0
- {aiq → nat}/settings/__init__.py +0 -0
- {aiq → nat}/test/.namespace +0 -0
- {aiq → nat}/tool/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/.gitignore +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/Dockerfile.sandbox +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/local_sandbox_server.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/sandbox.requirements.txt +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/start_local_sandbox.sh +0 -0
- {aiq → nat}/tool/code_execution/utils.py +0 -0
- {aiq → nat}/tool/github_tools/__init__.py +0 -0
- {aiq → nat}/tool/mcp/__init__.py +0 -0
- {aiq → nat}/tool/memory_tools/__init__.py +0 -0
- {aiq → nat}/tool/register.py +0 -0
- {aiq → nat}/utils/__init__.py +0 -0
- {aiq → nat}/utils/data_models/__init__.py +0 -0
- {aiq → nat}/utils/data_models/schema_validator.py +0 -0
- {aiq → nat}/utils/debugging_utils.py +0 -0
- {aiq → nat}/utils/exception_handlers/__init__.py +0 -0
- {aiq → nat}/utils/exception_handlers/automatic_retries.py +0 -0
- {aiq → nat}/utils/exception_handlers/schemas.py +0 -0
- {aiq → nat}/utils/io/__init__.py +0 -0
- {aiq → nat}/utils/io/model_processing.py +0 -0
- {aiq → nat}/utils/log_utils.py +0 -0
- {aiq → nat}/utils/optional_imports.py +0 -0
- {aiq → nat}/utils/producer_consumer_queue.py +0 -0
- {aiq → nat}/utils/reactive/__init__.py +0 -0
- {aiq → nat}/utils/reactive/base/__init__.py +0 -0
- {aiq → nat}/utils/reactive/base/observer_base.py +0 -0
- {aiq → nat}/utils/settings/__init__.py +0 -0
- {aiq → nat}/utils/string_utils.py +0 -0
- {aiq → nat}/utils/type_utils.py +0 -0
- {aiq → nat}/utils/url_utils.py +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc6.dist-info}/WHEEL +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc6.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc6.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -18,16 +18,16 @@ import logging
|
|
|
18
18
|
from functools import reduce
|
|
19
19
|
from textwrap import dedent
|
|
20
20
|
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
25
|
-
from
|
|
26
|
-
from
|
|
27
|
-
from
|
|
28
|
-
from
|
|
29
|
-
from
|
|
30
|
-
from
|
|
21
|
+
from nat.data_models.api_server import ResponseIntermediateStep
|
|
22
|
+
from nat.data_models.api_server import ResponseSerializable
|
|
23
|
+
from nat.data_models.intermediate_step import IntermediateStep
|
|
24
|
+
from nat.data_models.intermediate_step import IntermediateStepCategory
|
|
25
|
+
from nat.data_models.intermediate_step import IntermediateStepPayload
|
|
26
|
+
from nat.data_models.intermediate_step import IntermediateStepType
|
|
27
|
+
from nat.data_models.invocation_node import InvocationNode
|
|
28
|
+
from nat.data_models.step_adaptor import StepAdaptorConfig
|
|
29
|
+
from nat.data_models.step_adaptor import StepAdaptorMode
|
|
30
|
+
from nat.utils.type_utils import is_valid_json
|
|
31
31
|
|
|
32
32
|
logger = logging.getLogger(__name__)
|
|
33
33
|
|
|
@@ -63,7 +63,7 @@ class StepAdaptor:
|
|
|
63
63
|
|
|
64
64
|
return False
|
|
65
65
|
|
|
66
|
-
def _handle_llm(self, step: IntermediateStepPayload, ancestry: InvocationNode) ->
|
|
66
|
+
def _handle_llm(self, step: IntermediateStepPayload, ancestry: InvocationNode) -> ResponseSerializable | None:
|
|
67
67
|
input_str: str | None = None
|
|
68
68
|
output_str: str | None = None
|
|
69
69
|
|
|
@@ -113,14 +113,14 @@ class StepAdaptor:
|
|
|
113
113
|
{output_value}
|
|
114
114
|
""").strip("\n").format(payload=payload, output_value=escaped_output)
|
|
115
115
|
|
|
116
|
-
event =
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
event = ResponseIntermediateStep(id=step.UUID,
|
|
117
|
+
name=step.name or "",
|
|
118
|
+
payload=payload,
|
|
119
|
+
parent_id=ancestry.function_id)
|
|
120
120
|
|
|
121
121
|
return event
|
|
122
122
|
|
|
123
|
-
def _handle_tool(self, step: IntermediateStepPayload, ancestry: InvocationNode) ->
|
|
123
|
+
def _handle_tool(self, step: IntermediateStepPayload, ancestry: InvocationNode) -> ResponseSerializable | None:
|
|
124
124
|
"""
|
|
125
125
|
Handles both TOOL_START and TOOL_END events
|
|
126
126
|
"""
|
|
@@ -168,15 +168,14 @@ class StepAdaptor:
|
|
|
168
168
|
```
|
|
169
169
|
""").strip("\n").format(payload=payload, output_value=escaped_output, format_output_type=format_output_type)
|
|
170
170
|
|
|
171
|
-
event =
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
171
|
+
event = ResponseIntermediateStep(id=step.UUID,
|
|
172
|
+
name=f"Tool: {step.name}",
|
|
173
|
+
payload=payload,
|
|
174
|
+
parent_id=ancestry.function_id)
|
|
175
175
|
|
|
176
176
|
return event
|
|
177
177
|
|
|
178
|
-
def _handle_function(self, step: IntermediateStepPayload,
|
|
179
|
-
ancestry: InvocationNode) -> AIQResponseSerializable | None:
|
|
178
|
+
def _handle_function(self, step: IntermediateStepPayload, ancestry: InvocationNode) -> ResponseSerializable | None:
|
|
180
179
|
"""
|
|
181
180
|
Handles the FUNCTION_START and FUNCTION_END events
|
|
182
181
|
"""
|
|
@@ -204,10 +203,10 @@ class StepAdaptor:
|
|
|
204
203
|
```
|
|
205
204
|
""").strip("\n").format(input_value=escaped_input, format_input_type=format_input_type)
|
|
206
205
|
|
|
207
|
-
event =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
206
|
+
event = ResponseIntermediateStep(id=step.UUID,
|
|
207
|
+
name=f"Function Start: {step.name}",
|
|
208
|
+
payload=payload_str,
|
|
209
|
+
parent_id=ancestry.parent_id)
|
|
211
210
|
return event
|
|
212
211
|
|
|
213
212
|
if step.event_type == IntermediateStepType.FUNCTION_END:
|
|
@@ -257,16 +256,15 @@ class StepAdaptor:
|
|
|
257
256
|
output_value=escaped_output,
|
|
258
257
|
format_output_type=format_output_type)
|
|
259
258
|
|
|
260
|
-
event =
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
event = ResponseIntermediateStep(id=step.UUID,
|
|
260
|
+
name=f"Function Complete: {step.name}",
|
|
261
|
+
payload=payload_str,
|
|
262
|
+
parent_id=ancestry.parent_id)
|
|
264
263
|
return event
|
|
265
264
|
|
|
266
265
|
return None
|
|
267
266
|
|
|
268
|
-
def _handle_custom(self, payload: IntermediateStepPayload,
|
|
269
|
-
ancestry: InvocationNode) -> AIQResponseSerializable | None:
|
|
267
|
+
def _handle_custom(self, payload: IntermediateStepPayload, ancestry: InvocationNode) -> ResponseSerializable | None:
|
|
270
268
|
"""
|
|
271
269
|
Handles the CUSTOM event
|
|
272
270
|
"""
|
|
@@ -284,14 +282,14 @@ class StepAdaptor:
|
|
|
284
282
|
""").strip("\n").format(payload=escaped_payload, format_type=format_type)
|
|
285
283
|
|
|
286
284
|
# Return the event
|
|
287
|
-
event =
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
285
|
+
event = ResponseIntermediateStep(id=payload.UUID,
|
|
286
|
+
name=f"{payload.event_type}",
|
|
287
|
+
payload=payload_str,
|
|
288
|
+
parent_id=ancestry.function_id)
|
|
291
289
|
|
|
292
290
|
return event
|
|
293
291
|
|
|
294
|
-
def process(self, step: IntermediateStep) ->
|
|
292
|
+
def process(self, step: IntermediateStep) -> ResponseSerializable | None: # pylint: disable=R1710
|
|
295
293
|
|
|
296
294
|
# Track the chunk
|
|
297
295
|
self._history.append(step)
|
|
@@ -15,18 +15,22 @@
|
|
|
15
15
|
|
|
16
16
|
from pydantic import Field
|
|
17
17
|
|
|
18
|
-
from
|
|
18
|
+
from nat.data_models.front_end import FrontEndBaseConfig
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class MCPFrontEndConfig(FrontEndBaseConfig, name="mcp"):
|
|
22
22
|
"""MCP front end configuration.
|
|
23
23
|
|
|
24
|
-
A simple MCP (Modular Communication Protocol) front end for
|
|
24
|
+
A simple MCP (Modular Communication Protocol) front end for NeMo Agent toolkit.
|
|
25
25
|
"""
|
|
26
26
|
|
|
27
|
-
name: str = Field(default="
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
name: str = Field(default="NeMo Agent Toolkit MCP",
|
|
28
|
+
description="Name of the MCP server (default: NeMo Agent Toolkit MCP)")
|
|
29
|
+
host: str = Field(default="localhost", description="Host to bind the server to (default: localhost)")
|
|
30
|
+
port: int = Field(default=9901, description="Port to bind the server to (default: 9901)", ge=0, le=65535)
|
|
31
|
+
debug: bool = Field(default=False, description="Enable debug mode (default: False)")
|
|
32
|
+
log_level: str = Field(default="INFO", description="Log level for the MCP server (default: INFO)")
|
|
33
|
+
tool_names: list[str] = Field(default_factory=list,
|
|
34
|
+
description="The list of tools MCP server will expose (default: all tools)")
|
|
35
|
+
runner_class: str | None = Field(
|
|
36
|
+
default=None, description="Custom worker class for handling MCP routes (default: built-in worker)")
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 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 typing
|
|
18
|
+
|
|
19
|
+
from nat.builder.front_end import FrontEndBase
|
|
20
|
+
from nat.builder.workflow_builder import WorkflowBuilder
|
|
21
|
+
from nat.front_ends.mcp.mcp_front_end_config import MCPFrontEndConfig
|
|
22
|
+
from nat.front_ends.mcp.mcp_front_end_plugin_worker import MCPFrontEndPluginWorkerBase
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MCPFrontEndPlugin(FrontEndBase[MCPFrontEndConfig]):
|
|
28
|
+
"""MCP front end plugin implementation."""
|
|
29
|
+
|
|
30
|
+
def get_worker_class(self) -> type[MCPFrontEndPluginWorkerBase]:
|
|
31
|
+
"""Get the worker class for handling MCP routes."""
|
|
32
|
+
from nat.front_ends.mcp.mcp_front_end_plugin_worker import MCPFrontEndPluginWorker
|
|
33
|
+
|
|
34
|
+
return MCPFrontEndPluginWorker
|
|
35
|
+
|
|
36
|
+
@typing.final
|
|
37
|
+
def get_worker_class_name(self) -> str:
|
|
38
|
+
"""Get the worker class name from configuration or default."""
|
|
39
|
+
if self.front_end_config.runner_class:
|
|
40
|
+
return self.front_end_config.runner_class
|
|
41
|
+
|
|
42
|
+
worker_class = self.get_worker_class()
|
|
43
|
+
return f"{worker_class.__module__}.{worker_class.__qualname__}"
|
|
44
|
+
|
|
45
|
+
def _get_worker_instance(self) -> MCPFrontEndPluginWorkerBase:
|
|
46
|
+
"""Get an instance of the worker class."""
|
|
47
|
+
# Import the worker class dynamically if specified in config
|
|
48
|
+
if self.front_end_config.runner_class:
|
|
49
|
+
module_name, class_name = self.front_end_config.runner_class.rsplit(".", 1)
|
|
50
|
+
import importlib
|
|
51
|
+
module = importlib.import_module(module_name)
|
|
52
|
+
worker_class = getattr(module, class_name)
|
|
53
|
+
else:
|
|
54
|
+
worker_class = self.get_worker_class()
|
|
55
|
+
|
|
56
|
+
return worker_class(self.full_config)
|
|
57
|
+
|
|
58
|
+
async def run(self) -> None:
|
|
59
|
+
"""Run the MCP server."""
|
|
60
|
+
# Import FastMCP
|
|
61
|
+
from mcp.server.fastmcp import FastMCP
|
|
62
|
+
|
|
63
|
+
# Create an MCP server with the configured parameters
|
|
64
|
+
mcp = FastMCP(
|
|
65
|
+
self.front_end_config.name,
|
|
66
|
+
host=self.front_end_config.host,
|
|
67
|
+
port=self.front_end_config.port,
|
|
68
|
+
debug=self.front_end_config.debug,
|
|
69
|
+
log_level=self.front_end_config.log_level,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Get the worker instance and set up routes
|
|
73
|
+
worker = self._get_worker_instance()
|
|
74
|
+
|
|
75
|
+
# Build the workflow and add routes using the worker
|
|
76
|
+
async with WorkflowBuilder.from_config(config=self.full_config) as builder:
|
|
77
|
+
# Add routes through the worker (includes health endpoint and function registration)
|
|
78
|
+
await worker.add_routes(mcp, builder)
|
|
79
|
+
|
|
80
|
+
# Start the MCP server
|
|
81
|
+
await mcp.run_sse_async()
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 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
|
+
from abc import ABC
|
|
18
|
+
from abc import abstractmethod
|
|
19
|
+
|
|
20
|
+
from mcp.server.fastmcp import FastMCP
|
|
21
|
+
from starlette.requests import Request
|
|
22
|
+
|
|
23
|
+
from nat.builder.function import Function
|
|
24
|
+
from nat.builder.workflow import Workflow
|
|
25
|
+
from nat.builder.workflow_builder import WorkflowBuilder
|
|
26
|
+
from nat.data_models.config import Config
|
|
27
|
+
from nat.front_ends.mcp.mcp_front_end_config import MCPFrontEndConfig
|
|
28
|
+
|
|
29
|
+
logger = logging.getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class MCPFrontEndPluginWorkerBase(ABC):
|
|
33
|
+
"""Base class for MCP front end plugin workers."""
|
|
34
|
+
|
|
35
|
+
def __init__(self, config: Config):
|
|
36
|
+
"""Initialize the MCP worker with configuration.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
config: The full NAT configuration
|
|
40
|
+
"""
|
|
41
|
+
self.full_config = config
|
|
42
|
+
self.front_end_config: MCPFrontEndConfig = config.general.front_end
|
|
43
|
+
|
|
44
|
+
def _setup_health_endpoint(self, mcp: FastMCP):
|
|
45
|
+
"""Set up the HTTP health endpoint that exercises MCP ping handler."""
|
|
46
|
+
|
|
47
|
+
@mcp.custom_route("/health", methods=["GET"])
|
|
48
|
+
async def health_check(_request: Request):
|
|
49
|
+
"""HTTP health check using server's internal ping handler"""
|
|
50
|
+
from starlette.responses import JSONResponse
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
from mcp.types import PingRequest
|
|
54
|
+
|
|
55
|
+
# Create a ping request
|
|
56
|
+
ping_request = PingRequest(method="ping")
|
|
57
|
+
|
|
58
|
+
# Call the ping handler directly (same one that responds to MCP pings)
|
|
59
|
+
await mcp._mcp_server.request_handlers[PingRequest](ping_request)
|
|
60
|
+
|
|
61
|
+
return JSONResponse({
|
|
62
|
+
"status": "healthy",
|
|
63
|
+
"error": None,
|
|
64
|
+
"server_name": mcp.name,
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
except Exception as e:
|
|
68
|
+
return JSONResponse({
|
|
69
|
+
"status": "unhealthy",
|
|
70
|
+
"error": str(e),
|
|
71
|
+
"server_name": mcp.name,
|
|
72
|
+
},
|
|
73
|
+
status_code=503)
|
|
74
|
+
|
|
75
|
+
@abstractmethod
|
|
76
|
+
async def add_routes(self, mcp: FastMCP, builder: WorkflowBuilder):
|
|
77
|
+
"""Add routes to the MCP server.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
mcp: The FastMCP server instance
|
|
81
|
+
builder (WorkflowBuilder): The workflow builder instance
|
|
82
|
+
"""
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
def _get_all_functions(self, workflow: Workflow) -> dict[str, Function]:
|
|
86
|
+
"""Get all functions from the workflow.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
workflow: The NAT workflow.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Dict mapping function names to Function objects.
|
|
93
|
+
"""
|
|
94
|
+
functions: dict[str, Function] = {}
|
|
95
|
+
|
|
96
|
+
# Extract all functions from the workflow
|
|
97
|
+
for function_name, function in workflow.functions.items():
|
|
98
|
+
functions[function_name] = function
|
|
99
|
+
|
|
100
|
+
functions[workflow.config.workflow.type] = workflow
|
|
101
|
+
|
|
102
|
+
return functions
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class MCPFrontEndPluginWorker(MCPFrontEndPluginWorkerBase):
|
|
106
|
+
"""Default MCP front end plugin worker implementation."""
|
|
107
|
+
|
|
108
|
+
async def add_routes(self, mcp: FastMCP, builder: WorkflowBuilder):
|
|
109
|
+
"""Add default routes to the MCP server.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
mcp: The FastMCP server instance
|
|
113
|
+
builder (WorkflowBuilder): The workflow builder instance
|
|
114
|
+
"""
|
|
115
|
+
from nat.front_ends.mcp.tool_converter import register_function_with_mcp
|
|
116
|
+
|
|
117
|
+
# Set up the health endpoint
|
|
118
|
+
self._setup_health_endpoint(mcp)
|
|
119
|
+
|
|
120
|
+
# Build the workflow and register all functions with MCP
|
|
121
|
+
workflow = builder.build()
|
|
122
|
+
|
|
123
|
+
# Get all functions from the workflow
|
|
124
|
+
functions = self._get_all_functions(workflow)
|
|
125
|
+
|
|
126
|
+
# Filter functions based on tool_names if provided
|
|
127
|
+
if self.front_end_config.tool_names:
|
|
128
|
+
logger.info("Filtering functions based on tool_names: %s", self.front_end_config.tool_names)
|
|
129
|
+
filtered_functions: dict[str, Function] = {}
|
|
130
|
+
for function_name, function in functions.items():
|
|
131
|
+
if function_name in self.front_end_config.tool_names:
|
|
132
|
+
filtered_functions[function_name] = function
|
|
133
|
+
else:
|
|
134
|
+
logger.debug("Skipping function %s as it's not in tool_names", function_name)
|
|
135
|
+
functions = filtered_functions
|
|
136
|
+
|
|
137
|
+
# Register each function with MCP
|
|
138
|
+
for function_name, function in functions.items():
|
|
139
|
+
register_function_with_mcp(mcp, function_name, function)
|
|
140
|
+
|
|
141
|
+
# Add a simple fallback function if no functions were found
|
|
142
|
+
if not functions:
|
|
143
|
+
raise RuntimeError("No functions found in workflow. Please check your configuration.")
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
|
|
16
16
|
from collections.abc import AsyncIterator
|
|
17
17
|
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
18
|
+
from nat.cli.register_workflow import register_front_end
|
|
19
|
+
from nat.data_models.config import Config
|
|
20
|
+
from nat.front_ends.mcp.mcp_front_end_config import MCPFrontEndConfig
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
@register_front_end(config_type=MCPFrontEndConfig)
|
|
24
|
-
async def register_mcp_front_end(config: MCPFrontEndConfig, full_config:
|
|
25
|
-
from
|
|
24
|
+
async def register_mcp_front_end(config: MCPFrontEndConfig, full_config: Config) -> AsyncIterator:
|
|
25
|
+
from nat.front_ends.mcp.mcp_front_end_plugin import MCPFrontEndPlugin
|
|
26
26
|
|
|
27
27
|
yield MCPFrontEndPlugin(full_config=full_config)
|
|
@@ -21,9 +21,9 @@ from inspect import Signature
|
|
|
21
21
|
from mcp.server.fastmcp import FastMCP
|
|
22
22
|
from pydantic import BaseModel
|
|
23
23
|
|
|
24
|
-
from
|
|
25
|
-
from
|
|
26
|
-
from
|
|
24
|
+
from nat.builder.function import Function
|
|
25
|
+
from nat.builder.function_base import FunctionBase
|
|
26
|
+
from nat.builder.workflow import Workflow
|
|
27
27
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
@@ -34,27 +34,26 @@ def create_function_wrapper(
|
|
|
34
34
|
schema: type[BaseModel],
|
|
35
35
|
is_workflow: bool = False,
|
|
36
36
|
):
|
|
37
|
-
"""Create a wrapper function that exposes the actual parameters of
|
|
37
|
+
"""Create a wrapper function that exposes the actual parameters of a NAT Function as an MCP tool.
|
|
38
38
|
|
|
39
39
|
Args:
|
|
40
40
|
function_name: The name of the function/tool
|
|
41
|
-
function: The
|
|
41
|
+
function: The NAT Function object
|
|
42
42
|
schema: The input schema of the function
|
|
43
43
|
is_workflow: Whether the function is a Workflow
|
|
44
44
|
|
|
45
45
|
Returns:
|
|
46
46
|
A wrapper function suitable for registration with MCP
|
|
47
47
|
"""
|
|
48
|
-
# Check if we're dealing with
|
|
48
|
+
# Check if we're dealing with ChatRequest - special case
|
|
49
49
|
is_chat_request = False
|
|
50
50
|
|
|
51
|
-
# Check if the schema name is
|
|
52
|
-
if schema.__name__ == "
|
|
53
|
-
and "AIQChatRequest" in schema.__qualname__):
|
|
51
|
+
# Check if the schema name is ChatRequest
|
|
52
|
+
if schema.__name__ == "ChatRequest" or (hasattr(schema, "__qualname__") and "ChatRequest" in schema.__qualname__):
|
|
54
53
|
is_chat_request = True
|
|
55
|
-
logger.info("Function %s uses
|
|
54
|
+
logger.info("Function %s uses ChatRequest - creating simplified interface", function_name)
|
|
56
55
|
|
|
57
|
-
# For
|
|
56
|
+
# For ChatRequest, we'll create a simple wrapper with just a query parameter
|
|
58
57
|
parameters = [Parameter(
|
|
59
58
|
name="query",
|
|
60
59
|
kind=Parameter.KEYWORD_ONLY,
|
|
@@ -102,18 +101,18 @@ def create_function_wrapper(
|
|
|
102
101
|
await ctx.report_progress(0, 100)
|
|
103
102
|
|
|
104
103
|
try:
|
|
105
|
-
# Special handling for
|
|
104
|
+
# Special handling for ChatRequest
|
|
106
105
|
if is_chat_request:
|
|
107
|
-
from
|
|
106
|
+
from nat.data_models.api_server import ChatRequest
|
|
108
107
|
|
|
109
108
|
# Create a chat request from the query string
|
|
110
109
|
query = kwargs.get("query", "")
|
|
111
|
-
chat_request =
|
|
110
|
+
chat_request = ChatRequest.from_string(query)
|
|
112
111
|
|
|
113
112
|
# Special handling for Workflow objects
|
|
114
113
|
if is_workflow:
|
|
115
114
|
# Workflows have a run method that is an async context manager
|
|
116
|
-
# that returns
|
|
115
|
+
# that returns a Runner
|
|
117
116
|
async with function.run(chat_request) as runner:
|
|
118
117
|
# Get the result from the runner
|
|
119
118
|
result = await runner.result(to_type=str)
|
|
@@ -136,13 +135,13 @@ def create_function_wrapper(
|
|
|
136
135
|
# Call with the nested object
|
|
137
136
|
kwargs = {field_name: nested_obj}
|
|
138
137
|
|
|
139
|
-
# Call the
|
|
138
|
+
# Call the NAT function with the parameters - special handling for Workflow
|
|
140
139
|
if is_workflow:
|
|
141
140
|
# For workflow with regular input, we'll assume the first parameter is the input
|
|
142
141
|
input_value = list(kwargs.values())[0] if kwargs else ""
|
|
143
142
|
|
|
144
143
|
# Workflows have a run method that is an async context manager
|
|
145
|
-
# that returns
|
|
144
|
+
# that returns a Runner
|
|
146
145
|
async with function.run(input_value) as runner:
|
|
147
146
|
# Get the result from the runner
|
|
148
147
|
result = await runner.result(to_type=str)
|
|
@@ -180,7 +179,7 @@ def create_function_wrapper(
|
|
|
180
179
|
|
|
181
180
|
def get_function_description(function: FunctionBase) -> str:
|
|
182
181
|
"""
|
|
183
|
-
Retrieve a human-readable description for
|
|
182
|
+
Retrieve a human-readable description for a NAT function or workflow.
|
|
184
183
|
|
|
185
184
|
The description is determined using the following precedence:
|
|
186
185
|
1. If the function is a Workflow and has a 'description' attribute, use it.
|
|
@@ -189,7 +188,7 @@ def get_function_description(function: FunctionBase) -> str:
|
|
|
189
188
|
4. If the function is a regular Function, use its 'description' attribute.
|
|
190
189
|
|
|
191
190
|
Args:
|
|
192
|
-
function: The
|
|
191
|
+
function: The NAT FunctionBase instance (Function or Workflow).
|
|
193
192
|
|
|
194
193
|
Returns:
|
|
195
194
|
The best available description string for the function.
|
|
@@ -216,12 +215,12 @@ def get_function_description(function: FunctionBase) -> str:
|
|
|
216
215
|
|
|
217
216
|
|
|
218
217
|
def register_function_with_mcp(mcp: FastMCP, function_name: str, function: FunctionBase) -> None:
|
|
219
|
-
"""Register
|
|
218
|
+
"""Register a NAT Function as an MCP tool.
|
|
220
219
|
|
|
221
220
|
Args:
|
|
222
221
|
mcp: The FastMCP instance
|
|
223
222
|
function_name: The name to register the function under
|
|
224
|
-
function: The
|
|
223
|
+
function: The NAT Function to register
|
|
225
224
|
"""
|
|
226
225
|
logger.info("Registering function %s with MCP", function_name)
|
|
227
226
|
|
|
@@ -20,10 +20,10 @@ from io import StringIO
|
|
|
20
20
|
|
|
21
21
|
import click
|
|
22
22
|
|
|
23
|
-
from
|
|
24
|
-
from
|
|
25
|
-
from
|
|
26
|
-
from
|
|
23
|
+
from nat.builder.front_end import FrontEndBase
|
|
24
|
+
from nat.builder.workflow_builder import WorkflowBuilder
|
|
25
|
+
from nat.data_models.front_end import FrontEndConfigT
|
|
26
|
+
from nat.runtime.session import SessionManager
|
|
27
27
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
@@ -46,9 +46,9 @@ class SimpleFrontEndPluginBase(FrontEndBase[FrontEndConfigT], ABC):
|
|
|
46
46
|
click.echo(stream.getvalue())
|
|
47
47
|
|
|
48
48
|
workflow = builder.build()
|
|
49
|
-
session_manager =
|
|
49
|
+
session_manager = SessionManager(workflow)
|
|
50
50
|
await self.run_workflow(session_manager)
|
|
51
51
|
|
|
52
52
|
@abstractmethod
|
|
53
|
-
async def run_workflow(self, session_manager:
|
|
53
|
+
async def run_workflow(self, session_manager: SessionManager):
|
|
54
54
|
pass
|
|
@@ -17,11 +17,11 @@ from pydantic import AliasChoices
|
|
|
17
17
|
from pydantic import ConfigDict
|
|
18
18
|
from pydantic import Field
|
|
19
19
|
|
|
20
|
-
from
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
20
|
+
from nat.builder.builder import Builder
|
|
21
|
+
from nat.builder.llm import LLMProviderInfo
|
|
22
|
+
from nat.cli.register_workflow import register_llm_provider
|
|
23
|
+
from nat.data_models.llm import LLMBaseConfig
|
|
24
|
+
from nat.data_models.retry_mixin import RetryMixin
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class AWSBedrockModelConfig(LLMBaseConfig, RetryMixin, name="aws_bedrock"):
|
{aiq → nat}/llm/nim_llm.py
RENAMED
|
@@ -18,11 +18,11 @@ from pydantic import ConfigDict
|
|
|
18
18
|
from pydantic import Field
|
|
19
19
|
from pydantic import PositiveInt
|
|
20
20
|
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
25
|
-
from
|
|
21
|
+
from nat.builder.builder import Builder
|
|
22
|
+
from nat.builder.llm import LLMProviderInfo
|
|
23
|
+
from nat.cli.register_workflow import register_llm_provider
|
|
24
|
+
from nat.data_models.llm import LLMBaseConfig
|
|
25
|
+
from nat.data_models.retry_mixin import RetryMixin
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class NIMModelConfig(LLMBaseConfig, RetryMixin, name="nim"):
|
{aiq → nat}/llm/openai_llm.py
RENAMED
|
@@ -17,11 +17,11 @@ from pydantic import AliasChoices
|
|
|
17
17
|
from pydantic import ConfigDict
|
|
18
18
|
from pydantic import Field
|
|
19
19
|
|
|
20
|
-
from
|
|
21
|
-
from
|
|
22
|
-
from
|
|
23
|
-
from
|
|
24
|
-
from
|
|
20
|
+
from nat.builder.builder import Builder
|
|
21
|
+
from nat.builder.llm import LLMProviderInfo
|
|
22
|
+
from nat.cli.register_workflow import register_llm_provider
|
|
23
|
+
from nat.data_models.llm import LLMBaseConfig
|
|
24
|
+
from nat.data_models.retry_mixin import RetryMixin
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class OpenAIModelConfig(LLMBaseConfig, RetryMixin, name="openai"):
|
{aiq → nat}/memory/__init__.py
RENAMED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""
|
|
16
|
-
|
|
16
|
+
NAT Memory Module
|
|
17
17
|
|
|
18
18
|
This package provides foundational classes and interfaces
|
|
19
|
-
for managing text-based memory in
|
|
19
|
+
for managing text-based memory in NAT's LLM-based agents.
|
|
20
20
|
"""
|