nvidia-nat 1.3.0a20250828__py3-none-any.whl → 1.3.0a20250830__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.
- nat/agent/base.py +6 -1
- nat/agent/react_agent/agent.py +46 -38
- nat/agent/react_agent/register.py +7 -2
- nat/agent/rewoo_agent/agent.py +16 -30
- nat/agent/rewoo_agent/register.py +3 -3
- nat/agent/tool_calling_agent/agent.py +9 -19
- nat/agent/tool_calling_agent/register.py +2 -2
- nat/builder/eval_builder.py +2 -2
- nat/builder/function.py +8 -8
- nat/builder/workflow.py +6 -2
- nat/builder/workflow_builder.py +21 -24
- nat/cli/cli_utils/config_override.py +1 -1
- nat/cli/commands/info/list_channels.py +1 -1
- nat/cli/commands/info/list_mcp.py +183 -47
- nat/cli/commands/registry/publish.py +2 -2
- nat/cli/commands/registry/pull.py +2 -2
- nat/cli/commands/registry/remove.py +2 -2
- nat/cli/commands/registry/search.py +1 -1
- nat/cli/commands/start.py +15 -3
- nat/cli/commands/uninstall.py +1 -1
- nat/cli/commands/workflow/workflow_commands.py +4 -4
- nat/data_models/discovery_metadata.py +4 -4
- nat/data_models/thinking_mixin.py +27 -8
- nat/eval/evaluate.py +6 -6
- nat/eval/intermediate_step_adapter.py +1 -1
- nat/eval/rag_evaluator/evaluate.py +2 -2
- nat/eval/rag_evaluator/register.py +1 -1
- nat/eval/remote_workflow.py +3 -3
- nat/eval/swe_bench_evaluator/evaluate.py +5 -5
- nat/eval/trajectory_evaluator/evaluate.py +1 -1
- nat/eval/tunable_rag_evaluator/evaluate.py +3 -3
- nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +2 -2
- nat/front_ends/fastapi/fastapi_front_end_controller.py +4 -4
- nat/front_ends/fastapi/fastapi_front_end_plugin.py +1 -1
- nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py +3 -3
- nat/front_ends/fastapi/message_handler.py +2 -2
- nat/front_ends/fastapi/message_validator.py +8 -10
- nat/front_ends/fastapi/response_helpers.py +4 -4
- nat/front_ends/fastapi/step_adaptor.py +1 -1
- nat/front_ends/mcp/mcp_front_end_config.py +5 -0
- nat/front_ends/mcp/mcp_front_end_plugin.py +8 -2
- nat/front_ends/mcp/mcp_front_end_plugin_worker.py +2 -2
- nat/front_ends/mcp/tool_converter.py +40 -13
- nat/observability/exporter/base_exporter.py +1 -1
- nat/observability/exporter/processing_exporter.py +8 -9
- nat/observability/exporter_manager.py +5 -5
- nat/observability/mixin/file_mixin.py +7 -7
- nat/observability/processor/batching_processor.py +4 -6
- nat/observability/register.py +3 -1
- nat/profiler/calc/calc_runner.py +3 -4
- nat/profiler/callbacks/agno_callback_handler.py +1 -1
- nat/profiler/callbacks/langchain_callback_handler.py +5 -5
- nat/profiler/callbacks/llama_index_callback_handler.py +3 -3
- nat/profiler/callbacks/semantic_kernel_callback_handler.py +2 -2
- nat/profiler/profile_runner.py +1 -1
- nat/profiler/utils.py +1 -1
- nat/registry_handlers/local/local_handler.py +2 -2
- nat/registry_handlers/package_utils.py +1 -1
- nat/registry_handlers/pypi/pypi_handler.py +3 -3
- nat/registry_handlers/rest/rest_handler.py +4 -4
- nat/retriever/milvus/retriever.py +1 -1
- nat/retriever/nemo_retriever/retriever.py +1 -1
- nat/runtime/loader.py +1 -1
- nat/runtime/runner.py +2 -2
- nat/settings/global_settings.py +1 -1
- nat/tool/code_execution/local_sandbox/local_sandbox_server.py +1 -1
- nat/tool/mcp/{mcp_client.py → mcp_client_base.py} +197 -46
- nat/tool/mcp/mcp_client_impl.py +229 -0
- nat/tool/mcp/mcp_tool.py +79 -42
- nat/tool/nvidia_rag.py +1 -1
- nat/tool/register.py +1 -0
- nat/tool/retriever.py +3 -2
- nat/utils/io/yaml_tools.py +1 -1
- nat/utils/reactive/observer.py +2 -2
- nat/utils/settings/global_settings.py +2 -2
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/METADATA +3 -3
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/RECORD +82 -81
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/WHEEL +0 -0
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/entry_points.txt +0 -0
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/licenses/LICENSE.md +0 -0
- {nvidia_nat-1.3.0a20250828.dist-info → nvidia_nat-1.3.0a20250830.dist-info}/top_level.txt +0 -0
nat/tool/mcp/mcp_tool.py
CHANGED
|
@@ -14,10 +14,12 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
|
|
16
16
|
import logging
|
|
17
|
+
from typing import Literal
|
|
17
18
|
|
|
18
19
|
from pydantic import BaseModel
|
|
19
20
|
from pydantic import Field
|
|
20
21
|
from pydantic import HttpUrl
|
|
22
|
+
from pydantic import model_validator
|
|
21
23
|
|
|
22
24
|
from nat.builder.builder import Builder
|
|
23
25
|
from nat.builder.function_info import FunctionInfo
|
|
@@ -33,8 +35,16 @@ class MCPToolConfig(FunctionBaseConfig, name="mcp_tool_wrapper"):
|
|
|
33
35
|
function.
|
|
34
36
|
"""
|
|
35
37
|
# Add your custom configuration parameters here
|
|
36
|
-
url: HttpUrl = Field(
|
|
38
|
+
url: HttpUrl | None = Field(default=None,
|
|
39
|
+
description="The URL of the MCP server (for streamable-http or sse modes)")
|
|
37
40
|
mcp_tool_name: str = Field(description="The name of the tool served by the MCP Server that you want to use")
|
|
41
|
+
transport: Literal["sse", "stdio", "streamable-http"] = Field(
|
|
42
|
+
default="streamable-http",
|
|
43
|
+
description="The type of transport to use (default: streamable-http, backwards compatible with sse)")
|
|
44
|
+
command: str | None = Field(default=None,
|
|
45
|
+
description="The command to run for stdio mode (e.g. 'docker' or 'python')")
|
|
46
|
+
args: list[str] | None = Field(default=None, description="Additional arguments for the stdio command")
|
|
47
|
+
env: dict[str, str] | None = Field(default=None, description="Environment variables to set for the stdio process")
|
|
38
48
|
description: str | None = Field(default=None,
|
|
39
49
|
description="""
|
|
40
50
|
Description for the tool that will override the description provided by the MCP server. Should only be used if
|
|
@@ -46,51 +56,78 @@ class MCPToolConfig(FunctionBaseConfig, name="mcp_tool_wrapper"):
|
|
|
46
56
|
If false, raise the exception.
|
|
47
57
|
""")
|
|
48
58
|
|
|
59
|
+
@model_validator(mode="after")
|
|
60
|
+
def validate_model(self):
|
|
61
|
+
"""Validate that stdio and SSE/Streamable HTTP properties are mutually exclusive."""
|
|
62
|
+
if self.transport == 'stdio':
|
|
63
|
+
if self.url is not None:
|
|
64
|
+
raise ValueError("url should not be set when using stdio client type")
|
|
65
|
+
if not self.command:
|
|
66
|
+
raise ValueError("command is required when using stdio client type")
|
|
67
|
+
elif self.transport in ['streamable-http', 'sse']:
|
|
68
|
+
if self.command is not None or self.args is not None or self.env is not None:
|
|
69
|
+
raise ValueError(
|
|
70
|
+
"command, args, and env should not be set when using streamable-http or sse client type")
|
|
71
|
+
if not self.url:
|
|
72
|
+
raise ValueError("url is required when using streamable-http or sse client type")
|
|
73
|
+
return self
|
|
74
|
+
|
|
49
75
|
|
|
50
76
|
@register_function(config_type=MCPToolConfig)
|
|
51
77
|
async def mcp_tool(config: MCPToolConfig, builder: Builder):
|
|
52
78
|
"""
|
|
53
|
-
Generate a
|
|
79
|
+
Generate a NeMo Agent Toolkit Function that wraps a tool provided by the MCP server.
|
|
54
80
|
"""
|
|
55
81
|
|
|
56
|
-
from nat.tool.mcp.
|
|
57
|
-
from nat.tool.mcp.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if config.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
+
from nat.tool.mcp.mcp_client_base import MCPSSEClient
|
|
83
|
+
from nat.tool.mcp.mcp_client_base import MCPStdioClient
|
|
84
|
+
from nat.tool.mcp.mcp_client_base import MCPStreamableHTTPClient
|
|
85
|
+
from nat.tool.mcp.mcp_client_base import MCPToolClient
|
|
86
|
+
|
|
87
|
+
# Initialize the client
|
|
88
|
+
if config.transport == 'stdio':
|
|
89
|
+
client = MCPStdioClient(command=config.command, args=config.args, env=config.env)
|
|
90
|
+
elif config.transport == 'streamable-http':
|
|
91
|
+
client = MCPStreamableHTTPClient(url=str(config.url))
|
|
92
|
+
elif config.transport == 'sse':
|
|
93
|
+
client = MCPSSEClient(url=str(config.url))
|
|
94
|
+
else:
|
|
95
|
+
raise ValueError(f"Invalid transport type: {config.transport}")
|
|
96
|
+
|
|
97
|
+
async with client:
|
|
98
|
+
# If the tool is found create a MCPToolClient object and set the description if provided
|
|
99
|
+
tool: MCPToolClient = await client.get_tool(config.mcp_tool_name)
|
|
100
|
+
if config.description:
|
|
101
|
+
tool.set_description(description=config.description)
|
|
102
|
+
|
|
103
|
+
logger.info("Configured to use tool: %s from MCP server at %s", tool.name, client.server_name)
|
|
104
|
+
|
|
105
|
+
def _convert_from_str(input_str: str) -> tool.input_schema:
|
|
106
|
+
return tool.input_schema.model_validate_json(input_str)
|
|
107
|
+
|
|
108
|
+
async def _response_fn(tool_input: BaseModel | None = None, **kwargs) -> str:
|
|
109
|
+
# Run the tool, catching any errors and sending to agent for correction
|
|
110
|
+
try:
|
|
82
111
|
if tool_input:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
args = tool_input.model_dump()
|
|
113
|
+
return await tool.acall(args)
|
|
114
|
+
|
|
115
|
+
_ = tool.input_schema.model_validate(kwargs)
|
|
116
|
+
return await tool.acall(kwargs)
|
|
117
|
+
except Exception as e:
|
|
118
|
+
if config.return_exception:
|
|
119
|
+
if tool_input:
|
|
120
|
+
logger.warning("Error calling tool %s with serialized input: %s",
|
|
121
|
+
tool.name,
|
|
122
|
+
tool_input.model_dump(),
|
|
123
|
+
exc_info=True)
|
|
124
|
+
else:
|
|
125
|
+
logger.warning("Error calling tool %s with input: %s", tool.name, kwargs, exc_info=True)
|
|
126
|
+
return str(e)
|
|
127
|
+
# If the tool call fails, raise the exception.
|
|
128
|
+
raise
|
|
129
|
+
|
|
130
|
+
yield FunctionInfo.create(single_fn=_response_fn,
|
|
131
|
+
description=tool.description,
|
|
132
|
+
input_schema=tool.input_schema,
|
|
133
|
+
converters=[_convert_from_str])
|
nat/tool/nvidia_rag.py
CHANGED
|
@@ -86,7 +86,7 @@ async def nvidia_rag_tool(config: NVIDIARAGToolConfig, builder: Builder):
|
|
|
86
86
|
[await aformat_document(doc, document_prompt) for doc in docs])
|
|
87
87
|
return parsed_output
|
|
88
88
|
except Exception as e:
|
|
89
|
-
logger.exception("Error while running the tool"
|
|
89
|
+
logger.exception("Error while running the tool")
|
|
90
90
|
return f"Error while running the tool: {e}"
|
|
91
91
|
|
|
92
92
|
yield FunctionInfo.from_fn(
|
nat/tool/register.py
CHANGED
|
@@ -31,6 +31,7 @@ from .github_tools import get_github_file
|
|
|
31
31
|
from .github_tools import get_github_issue
|
|
32
32
|
from .github_tools import get_github_pr
|
|
33
33
|
from .github_tools import update_github_issue
|
|
34
|
+
from .mcp import mcp_client_impl
|
|
34
35
|
from .mcp import mcp_tool
|
|
35
36
|
from .memory_tools import add_memory_tool
|
|
36
37
|
from .memory_tools import delete_memory_tool
|
nat/tool/retriever.py
CHANGED
|
@@ -78,8 +78,9 @@ async def retriever_tool(config: RetrieverConfig, builder: Builder):
|
|
|
78
78
|
|
|
79
79
|
except RetrieverError as e:
|
|
80
80
|
if config.raise_errors:
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
logger.error("Retriever threw an error: %s.", e)
|
|
82
|
+
raise
|
|
83
|
+
logger.exception("Retriever threw an error: %s. Returning an empty response.", e)
|
|
83
84
|
return RetrieverOutput(results=[])
|
|
84
85
|
|
|
85
86
|
yield FunctionInfo.from_fn(
|
nat/utils/io/yaml_tools.py
CHANGED
|
@@ -85,7 +85,7 @@ def yaml_loads(config: str) -> dict:
|
|
|
85
85
|
try:
|
|
86
86
|
config_data = yaml.safe_load(stream)
|
|
87
87
|
except yaml.YAMLError as e:
|
|
88
|
-
logger.error("Error loading YAML: %s", interpolated_config_str
|
|
88
|
+
logger.error("Error loading YAML: %s", interpolated_config_str)
|
|
89
89
|
raise ValueError(f"Error loading YAML: {e}") from e
|
|
90
90
|
|
|
91
91
|
assert isinstance(config_data, dict)
|
nat/utils/reactive/observer.py
CHANGED
|
@@ -64,7 +64,7 @@ class Observer(ObserverBase[_T_in_contra]):
|
|
|
64
64
|
try:
|
|
65
65
|
self._on_error(exc)
|
|
66
66
|
except Exception as e:
|
|
67
|
-
logger.exception("Error in on_error callback: %s", e
|
|
67
|
+
logger.exception("Error in on_error callback: %s", e)
|
|
68
68
|
|
|
69
69
|
def on_complete(self) -> None:
|
|
70
70
|
if not self._stopped:
|
|
@@ -73,4 +73,4 @@ class Observer(ObserverBase[_T_in_contra]):
|
|
|
73
73
|
try:
|
|
74
74
|
self._on_complete()
|
|
75
75
|
except Exception as e:
|
|
76
|
-
logger.exception("Error in on_complete callback: %s", e
|
|
76
|
+
logger.exception("Error in on_complete callback: %s", e)
|
|
@@ -55,7 +55,7 @@ def configure_registry_channel(config_type: RegistryHandlerBaseConfig, channel_n
|
|
|
55
55
|
channel_registry_pre[field] = getattr(validated_field_model, field)
|
|
56
56
|
break
|
|
57
57
|
except Exception as e:
|
|
58
|
-
logger.exception(e
|
|
58
|
+
logger.exception(e)
|
|
59
59
|
logger.warning("Invalid '%s' input, input must be of type %s.", field, info.annotation)
|
|
60
60
|
|
|
61
61
|
validated_model = config_type(**channel_registry_pre)
|
|
@@ -78,7 +78,7 @@ def add_channel_interative(channel_type: str) -> None:
|
|
|
78
78
|
try:
|
|
79
79
|
ChannelConfigType = registry.get_registered_channel_info_by_channel_type(channel_type=channel_type).config_type
|
|
80
80
|
except Exception as e:
|
|
81
|
-
logger.exception("Invalid channel type: %s", e
|
|
81
|
+
logger.exception("Invalid channel type: %s", e)
|
|
82
82
|
return
|
|
83
83
|
|
|
84
84
|
while (True):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nvidia-nat
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.0a20250830
|
|
4
4
|
Summary: NVIDIA NeMo Agent toolkit
|
|
5
5
|
Author: NVIDIA Corporation
|
|
6
6
|
Maintainer: NVIDIA Corporation
|
|
@@ -221,7 +221,7 @@ Requires-Dist: fastapi~=0.115.5
|
|
|
221
221
|
Requires-Dist: httpx~=0.27
|
|
222
222
|
Requires-Dist: jinja2~=3.1
|
|
223
223
|
Requires-Dist: jsonpath-ng~=1.7
|
|
224
|
-
Requires-Dist: mcp~=1.
|
|
224
|
+
Requires-Dist: mcp~=1.13
|
|
225
225
|
Requires-Dist: networkx~=3.4
|
|
226
226
|
Requires-Dist: numpy~=1.26
|
|
227
227
|
Requires-Dist: openinference-semantic-conventions~=0.1.14
|
|
@@ -229,7 +229,7 @@ Requires-Dist: openpyxl~=3.1
|
|
|
229
229
|
Requires-Dist: pkce==1.0.3
|
|
230
230
|
Requires-Dist: pkginfo~=1.12
|
|
231
231
|
Requires-Dist: platformdirs~=4.3
|
|
232
|
-
Requires-Dist: pydantic
|
|
232
|
+
Requires-Dist: pydantic~=2.11
|
|
233
233
|
Requires-Dist: pymilvus~=2.4
|
|
234
234
|
Requires-Dist: PyYAML~=6.0
|
|
235
235
|
Requires-Dist: ragas~=0.2.14
|