nvidia-nat 1.2.1rc1__py3-none-any.whl → 1.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. aiq/__init__.py +2 -2
  2. nat/agent/base.py +27 -18
  3. nat/agent/dual_node.py +9 -4
  4. nat/agent/prompt_optimizer/prompt.py +68 -0
  5. nat/agent/prompt_optimizer/register.py +149 -0
  6. nat/agent/react_agent/agent.py +81 -50
  7. nat/agent/react_agent/register.py +59 -40
  8. nat/agent/reasoning_agent/reasoning_agent.py +17 -15
  9. nat/agent/register.py +1 -1
  10. nat/agent/rewoo_agent/agent.py +327 -149
  11. nat/agent/rewoo_agent/prompt.py +19 -22
  12. nat/agent/rewoo_agent/register.py +64 -46
  13. nat/agent/tool_calling_agent/agent.py +152 -29
  14. nat/agent/tool_calling_agent/register.py +61 -38
  15. nat/authentication/api_key/api_key_auth_provider.py +2 -2
  16. nat/authentication/credential_validator/bearer_token_validator.py +557 -0
  17. nat/authentication/http_basic_auth/http_basic_auth_provider.py +1 -1
  18. nat/authentication/interfaces.py +5 -2
  19. nat/authentication/oauth2/oauth2_auth_code_flow_provider.py +69 -36
  20. nat/authentication/oauth2/oauth2_resource_server_config.py +124 -0
  21. nat/authentication/register.py +0 -1
  22. nat/builder/builder.py +56 -24
  23. nat/builder/component_utils.py +10 -6
  24. nat/builder/context.py +70 -18
  25. nat/builder/eval_builder.py +16 -11
  26. nat/builder/framework_enum.py +1 -0
  27. nat/builder/front_end.py +1 -1
  28. nat/builder/function.py +378 -8
  29. nat/builder/function_base.py +3 -3
  30. nat/builder/function_info.py +6 -8
  31. nat/builder/intermediate_step_manager.py +6 -2
  32. nat/builder/user_interaction_manager.py +2 -2
  33. nat/builder/workflow.py +13 -1
  34. nat/builder/workflow_builder.py +327 -79
  35. nat/cli/cli_utils/config_override.py +2 -2
  36. nat/cli/commands/evaluate.py +1 -1
  37. nat/cli/commands/info/info.py +16 -6
  38. nat/cli/commands/info/list_channels.py +1 -1
  39. nat/cli/commands/info/list_components.py +7 -8
  40. nat/cli/commands/mcp/__init__.py +14 -0
  41. nat/cli/commands/mcp/mcp.py +986 -0
  42. nat/cli/commands/object_store/__init__.py +14 -0
  43. nat/cli/commands/object_store/object_store.py +227 -0
  44. nat/cli/commands/optimize.py +90 -0
  45. nat/cli/commands/registry/publish.py +2 -2
  46. nat/cli/commands/registry/pull.py +2 -2
  47. nat/cli/commands/registry/remove.py +2 -2
  48. nat/cli/commands/registry/search.py +15 -17
  49. nat/cli/commands/start.py +16 -5
  50. nat/cli/commands/uninstall.py +1 -1
  51. nat/cli/commands/workflow/templates/config.yml.j2 +14 -13
  52. nat/cli/commands/workflow/templates/pyproject.toml.j2 +5 -2
  53. nat/cli/commands/workflow/templates/register.py.j2 +2 -3
  54. nat/cli/commands/workflow/templates/workflow.py.j2 +35 -21
  55. nat/cli/commands/workflow/workflow_commands.py +105 -19
  56. nat/cli/entrypoint.py +17 -11
  57. nat/cli/main.py +3 -0
  58. nat/cli/register_workflow.py +38 -4
  59. nat/cli/type_registry.py +79 -10
  60. nat/control_flow/__init__.py +0 -0
  61. nat/control_flow/register.py +20 -0
  62. nat/control_flow/router_agent/__init__.py +0 -0
  63. nat/control_flow/router_agent/agent.py +329 -0
  64. nat/control_flow/router_agent/prompt.py +48 -0
  65. nat/control_flow/router_agent/register.py +91 -0
  66. nat/control_flow/sequential_executor.py +166 -0
  67. nat/data_models/agent.py +34 -0
  68. nat/data_models/api_server.py +196 -67
  69. nat/data_models/authentication.py +23 -9
  70. nat/data_models/common.py +1 -1
  71. nat/data_models/component.py +2 -0
  72. nat/data_models/component_ref.py +11 -0
  73. nat/data_models/config.py +42 -18
  74. nat/data_models/dataset_handler.py +1 -1
  75. nat/data_models/discovery_metadata.py +4 -4
  76. nat/data_models/evaluate.py +4 -1
  77. nat/data_models/function.py +34 -0
  78. nat/data_models/function_dependencies.py +14 -6
  79. nat/data_models/gated_field_mixin.py +242 -0
  80. nat/data_models/intermediate_step.py +3 -3
  81. nat/data_models/optimizable.py +119 -0
  82. nat/data_models/optimizer.py +149 -0
  83. nat/data_models/span.py +41 -3
  84. nat/data_models/swe_bench_model.py +1 -1
  85. nat/data_models/temperature_mixin.py +44 -0
  86. nat/data_models/thinking_mixin.py +86 -0
  87. nat/data_models/top_p_mixin.py +44 -0
  88. nat/embedder/azure_openai_embedder.py +46 -0
  89. nat/embedder/nim_embedder.py +1 -1
  90. nat/embedder/openai_embedder.py +2 -3
  91. nat/embedder/register.py +1 -1
  92. nat/eval/config.py +3 -1
  93. nat/eval/dataset_handler/dataset_handler.py +71 -7
  94. nat/eval/evaluate.py +86 -31
  95. nat/eval/evaluator/base_evaluator.py +1 -1
  96. nat/eval/evaluator/evaluator_model.py +13 -0
  97. nat/eval/intermediate_step_adapter.py +1 -1
  98. nat/eval/rag_evaluator/evaluate.py +9 -6
  99. nat/eval/rag_evaluator/register.py +3 -3
  100. nat/eval/register.py +4 -1
  101. nat/eval/remote_workflow.py +3 -3
  102. nat/eval/runtime_evaluator/__init__.py +14 -0
  103. nat/eval/runtime_evaluator/evaluate.py +123 -0
  104. nat/eval/runtime_evaluator/register.py +100 -0
  105. nat/eval/swe_bench_evaluator/evaluate.py +6 -6
  106. nat/eval/trajectory_evaluator/evaluate.py +1 -1
  107. nat/eval/trajectory_evaluator/register.py +1 -1
  108. nat/eval/tunable_rag_evaluator/evaluate.py +4 -7
  109. nat/eval/utils/eval_trace_ctx.py +89 -0
  110. nat/eval/utils/weave_eval.py +18 -9
  111. nat/experimental/decorators/experimental_warning_decorator.py +27 -7
  112. nat/experimental/test_time_compute/functions/execute_score_select_function.py +1 -1
  113. nat/experimental/test_time_compute/functions/plan_select_execute_function.py +7 -3
  114. nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +3 -3
  115. nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +3 -3
  116. nat/experimental/test_time_compute/models/strategy_base.py +5 -4
  117. nat/experimental/test_time_compute/register.py +0 -1
  118. nat/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +1 -3
  119. nat/front_ends/console/authentication_flow_handler.py +82 -30
  120. nat/front_ends/console/console_front_end_plugin.py +19 -7
  121. nat/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +1 -1
  122. nat/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +52 -17
  123. nat/front_ends/fastapi/dask_client_mixin.py +65 -0
  124. nat/front_ends/fastapi/fastapi_front_end_config.py +36 -5
  125. nat/front_ends/fastapi/fastapi_front_end_controller.py +4 -4
  126. nat/front_ends/fastapi/fastapi_front_end_plugin.py +135 -4
  127. nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py +455 -282
  128. nat/front_ends/fastapi/job_store.py +518 -99
  129. nat/front_ends/fastapi/main.py +11 -19
  130. nat/front_ends/fastapi/message_handler.py +74 -50
  131. nat/front_ends/fastapi/message_validator.py +20 -21
  132. nat/front_ends/fastapi/response_helpers.py +4 -4
  133. nat/front_ends/fastapi/step_adaptor.py +2 -2
  134. nat/front_ends/fastapi/utils.py +57 -0
  135. nat/front_ends/mcp/introspection_token_verifier.py +73 -0
  136. nat/front_ends/mcp/mcp_front_end_config.py +47 -3
  137. nat/front_ends/mcp/mcp_front_end_plugin.py +48 -13
  138. nat/front_ends/mcp/mcp_front_end_plugin_worker.py +120 -8
  139. nat/front_ends/mcp/tool_converter.py +44 -14
  140. nat/front_ends/register.py +0 -1
  141. nat/front_ends/simple_base/simple_front_end_plugin_base.py +3 -1
  142. nat/llm/aws_bedrock_llm.py +24 -12
  143. nat/llm/azure_openai_llm.py +57 -0
  144. nat/llm/litellm_llm.py +69 -0
  145. nat/llm/nim_llm.py +20 -8
  146. nat/llm/openai_llm.py +14 -6
  147. nat/llm/register.py +5 -1
  148. nat/llm/utils/env_config_value.py +2 -3
  149. nat/llm/utils/thinking.py +215 -0
  150. nat/meta/pypi.md +9 -9
  151. nat/object_store/register.py +0 -1
  152. nat/observability/exporter/base_exporter.py +3 -3
  153. nat/observability/exporter/file_exporter.py +1 -1
  154. nat/observability/exporter/processing_exporter.py +309 -81
  155. nat/observability/exporter/span_exporter.py +35 -15
  156. nat/observability/exporter_manager.py +7 -7
  157. nat/observability/mixin/file_mixin.py +7 -7
  158. nat/observability/mixin/redaction_config_mixin.py +42 -0
  159. nat/observability/mixin/tagging_config_mixin.py +62 -0
  160. nat/observability/mixin/type_introspection_mixin.py +420 -107
  161. nat/observability/processor/batching_processor.py +5 -7
  162. nat/observability/processor/falsy_batch_filter_processor.py +55 -0
  163. nat/observability/processor/processor.py +3 -0
  164. nat/observability/processor/processor_factory.py +70 -0
  165. nat/observability/processor/redaction/__init__.py +24 -0
  166. nat/observability/processor/redaction/contextual_redaction_processor.py +125 -0
  167. nat/observability/processor/redaction/contextual_span_redaction_processor.py +66 -0
  168. nat/observability/processor/redaction/redaction_processor.py +177 -0
  169. nat/observability/processor/redaction/span_header_redaction_processor.py +92 -0
  170. nat/observability/processor/span_tagging_processor.py +68 -0
  171. nat/observability/register.py +22 -4
  172. nat/profiler/calc/calc_runner.py +3 -4
  173. nat/profiler/callbacks/agno_callback_handler.py +1 -1
  174. nat/profiler/callbacks/langchain_callback_handler.py +14 -7
  175. nat/profiler/callbacks/llama_index_callback_handler.py +3 -3
  176. nat/profiler/callbacks/semantic_kernel_callback_handler.py +3 -3
  177. nat/profiler/data_frame_row.py +1 -1
  178. nat/profiler/decorators/framework_wrapper.py +62 -13
  179. nat/profiler/decorators/function_tracking.py +160 -3
  180. nat/profiler/forecasting/models/forecasting_base_model.py +3 -1
  181. nat/profiler/forecasting/models/linear_model.py +1 -1
  182. nat/profiler/forecasting/models/random_forest_regressor.py +1 -1
  183. nat/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +1 -1
  184. nat/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +1 -1
  185. nat/profiler/inference_optimization/data_models.py +3 -3
  186. nat/profiler/inference_optimization/experimental/prefix_span_analysis.py +8 -9
  187. nat/profiler/inference_optimization/token_uniqueness.py +1 -1
  188. nat/profiler/parameter_optimization/__init__.py +0 -0
  189. nat/profiler/parameter_optimization/optimizable_utils.py +93 -0
  190. nat/profiler/parameter_optimization/optimizer_runtime.py +67 -0
  191. nat/profiler/parameter_optimization/parameter_optimizer.py +164 -0
  192. nat/profiler/parameter_optimization/parameter_selection.py +107 -0
  193. nat/profiler/parameter_optimization/pareto_visualizer.py +395 -0
  194. nat/profiler/parameter_optimization/prompt_optimizer.py +384 -0
  195. nat/profiler/parameter_optimization/update_helpers.py +66 -0
  196. nat/profiler/profile_runner.py +14 -9
  197. nat/profiler/utils.py +4 -2
  198. nat/registry_handlers/local/local_handler.py +2 -2
  199. nat/registry_handlers/package_utils.py +1 -2
  200. nat/registry_handlers/pypi/pypi_handler.py +23 -26
  201. nat/registry_handlers/register.py +3 -4
  202. nat/registry_handlers/rest/rest_handler.py +12 -13
  203. nat/retriever/milvus/retriever.py +2 -2
  204. nat/retriever/nemo_retriever/retriever.py +1 -1
  205. nat/retriever/register.py +0 -1
  206. nat/runtime/loader.py +2 -2
  207. nat/runtime/runner.py +105 -8
  208. nat/runtime/session.py +69 -8
  209. nat/settings/global_settings.py +16 -5
  210. nat/tool/chat_completion.py +5 -2
  211. nat/tool/code_execution/local_sandbox/local_sandbox_server.py +3 -3
  212. nat/tool/datetime_tools.py +49 -9
  213. nat/tool/document_search.py +2 -2
  214. nat/tool/github_tools.py +450 -0
  215. nat/tool/memory_tools/add_memory_tool.py +3 -3
  216. nat/tool/memory_tools/delete_memory_tool.py +3 -4
  217. nat/tool/memory_tools/get_memory_tool.py +4 -4
  218. nat/tool/nvidia_rag.py +1 -1
  219. nat/tool/register.py +2 -9
  220. nat/tool/retriever.py +3 -2
  221. nat/utils/callable_utils.py +70 -0
  222. nat/utils/data_models/schema_validator.py +3 -3
  223. nat/utils/decorators.py +210 -0
  224. nat/utils/exception_handlers/automatic_retries.py +104 -51
  225. nat/utils/exception_handlers/schemas.py +1 -1
  226. nat/utils/io/yaml_tools.py +2 -2
  227. nat/utils/log_levels.py +25 -0
  228. nat/utils/reactive/base/observable_base.py +2 -2
  229. nat/utils/reactive/base/observer_base.py +1 -1
  230. nat/utils/reactive/observable.py +2 -2
  231. nat/utils/reactive/observer.py +4 -4
  232. nat/utils/reactive/subscription.py +1 -1
  233. nat/utils/settings/global_settings.py +6 -8
  234. nat/utils/type_converter.py +12 -3
  235. nat/utils/type_utils.py +9 -5
  236. nvidia_nat-1.3.0.dist-info/METADATA +195 -0
  237. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/RECORD +244 -200
  238. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/entry_points.txt +1 -0
  239. nat/cli/commands/info/list_mcp.py +0 -304
  240. nat/tool/github_tools/create_github_commit.py +0 -133
  241. nat/tool/github_tools/create_github_issue.py +0 -87
  242. nat/tool/github_tools/create_github_pr.py +0 -106
  243. nat/tool/github_tools/get_github_file.py +0 -106
  244. nat/tool/github_tools/get_github_issue.py +0 -166
  245. nat/tool/github_tools/get_github_pr.py +0 -256
  246. nat/tool/github_tools/update_github_issue.py +0 -100
  247. nat/tool/mcp/exceptions.py +0 -142
  248. nat/tool/mcp/mcp_client.py +0 -255
  249. nat/tool/mcp/mcp_tool.py +0 -96
  250. nat/utils/exception_handlers/mcp.py +0 -211
  251. nvidia_nat-1.2.1rc1.dist-info/METADATA +0 -365
  252. /nat/{tool/github_tools → agent/prompt_optimizer}/__init__.py +0 -0
  253. /nat/{tool/mcp → authentication/credential_validator}/__init__.py +0 -0
  254. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/WHEEL +0 -0
  255. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
  256. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/licenses/LICENSE.md +0 -0
  257. {nvidia_nat-1.2.1rc1.dist-info → nvidia_nat-1.3.0.dist-info}/top_level.txt +0 -0
nat/llm/litellm_llm.py ADDED
@@ -0,0 +1,69 @@
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
+ from collections.abc import AsyncIterator
17
+
18
+ from pydantic import AliasChoices
19
+ from pydantic import ConfigDict
20
+ from pydantic import Field
21
+
22
+ from nat.builder.builder import Builder
23
+ from nat.builder.llm import LLMProviderInfo
24
+ from nat.cli.register_workflow import register_llm_provider
25
+ from nat.data_models.llm import LLMBaseConfig
26
+ from nat.data_models.retry_mixin import RetryMixin
27
+ from nat.data_models.temperature_mixin import TemperatureMixin
28
+ from nat.data_models.thinking_mixin import ThinkingMixin
29
+ from nat.data_models.top_p_mixin import TopPMixin
30
+
31
+
32
+ class LiteLlmModelConfig(
33
+ LLMBaseConfig,
34
+ RetryMixin,
35
+ TemperatureMixin,
36
+ TopPMixin,
37
+ ThinkingMixin,
38
+ name="litellm",
39
+ ):
40
+ """A LiteLlm provider to be used with an LLM client."""
41
+
42
+ model_config = ConfigDict(protected_namespaces=(), extra="allow")
43
+
44
+ api_key: str | None = Field(default=None, description="API key to interact with hosted model.")
45
+ base_url: str | None = Field(default=None,
46
+ description="Base url to the hosted model.",
47
+ validation_alias=AliasChoices("base_url", "api_base"),
48
+ serialization_alias="api_base")
49
+ model_name: str = Field(validation_alias=AliasChoices("model_name", "model"),
50
+ serialization_alias="model",
51
+ description="The LiteLlm hosted model name.")
52
+ seed: int | None = Field(default=None, description="Random seed to set for generation.")
53
+
54
+
55
+ @register_llm_provider(config_type=LiteLlmModelConfig)
56
+ async def litellm_model(
57
+ config: LiteLlmModelConfig,
58
+ _builder: Builder,
59
+ ) -> AsyncIterator[LLMProviderInfo]:
60
+ """Litellm model provider.
61
+
62
+ Args:
63
+ config (LiteLlmModelConfig): The LiteLlm model configuration.
64
+ _builder (Builder): The NAT builder instance.
65
+
66
+ Returns:
67
+ AsyncIterator[LLMProviderInfo]: An async iterator that yields an LLMProviderInfo object.
68
+ """
69
+ yield LLMProviderInfo(config=config, description="A LiteLlm model for use with an LLM client.")
nat/llm/nim_llm.py CHANGED
@@ -22,25 +22,37 @@ from nat.builder.builder import Builder
22
22
  from nat.builder.llm import LLMProviderInfo
23
23
  from nat.cli.register_workflow import register_llm_provider
24
24
  from nat.data_models.llm import LLMBaseConfig
25
+ from nat.data_models.optimizable import OptimizableField
26
+ from nat.data_models.optimizable import OptimizableMixin
27
+ from nat.data_models.optimizable import SearchSpace
25
28
  from nat.data_models.retry_mixin import RetryMixin
26
-
27
-
28
- class NIMModelConfig(LLMBaseConfig, RetryMixin, name="nim"):
29
+ from nat.data_models.temperature_mixin import TemperatureMixin
30
+ from nat.data_models.thinking_mixin import ThinkingMixin
31
+ from nat.data_models.top_p_mixin import TopPMixin
32
+
33
+
34
+ class NIMModelConfig(LLMBaseConfig,
35
+ RetryMixin,
36
+ OptimizableMixin,
37
+ TemperatureMixin,
38
+ TopPMixin,
39
+ ThinkingMixin,
40
+ name="nim"):
29
41
  """An NVIDIA Inference Microservice (NIM) llm provider to be used with an LLM client."""
30
42
 
31
- model_config = ConfigDict(protected_namespaces=())
43
+ model_config = ConfigDict(protected_namespaces=(), extra="allow")
32
44
 
33
45
  api_key: str | None = Field(default=None, description="NVIDIA API key to interact with hosted NIM.")
34
46
  base_url: str | None = Field(default=None, description="Base url to the hosted NIM.")
35
47
  model_name: str = Field(validation_alias=AliasChoices("model_name", "model"),
36
48
  serialization_alias="model",
37
49
  description="The model name for the hosted NIM.")
38
- temperature: float = Field(default=0.0, description="Sampling temperature in [0, 1].")
39
- top_p: float = Field(default=1.0, description="Top-p for distribution sampling.")
40
- max_tokens: PositiveInt = Field(default=300, description="Maximum number of tokens to generate.")
50
+ max_tokens: PositiveInt = OptimizableField(default=300,
51
+ description="Maximum number of tokens to generate.",
52
+ space=SearchSpace(high=2176, low=128, step=512))
41
53
 
42
54
 
43
55
  @register_llm_provider(config_type=NIMModelConfig)
44
- async def nim_model(llm_config: NIMModelConfig, builder: Builder):
56
+ async def nim_model(llm_config: NIMModelConfig, _builder: Builder):
45
57
 
46
58
  yield LLMProviderInfo(config=llm_config, description="A NIM model for use with an LLM client.")
nat/llm/openai_llm.py CHANGED
@@ -21,10 +21,20 @@ from nat.builder.builder import Builder
21
21
  from nat.builder.llm import LLMProviderInfo
22
22
  from nat.cli.register_workflow import register_llm_provider
23
23
  from nat.data_models.llm import LLMBaseConfig
24
+ from nat.data_models.optimizable import OptimizableMixin
24
25
  from nat.data_models.retry_mixin import RetryMixin
25
-
26
-
27
- class OpenAIModelConfig(LLMBaseConfig, RetryMixin, name="openai"):
26
+ from nat.data_models.temperature_mixin import TemperatureMixin
27
+ from nat.data_models.thinking_mixin import ThinkingMixin
28
+ from nat.data_models.top_p_mixin import TopPMixin
29
+
30
+
31
+ class OpenAIModelConfig(LLMBaseConfig,
32
+ RetryMixin,
33
+ OptimizableMixin,
34
+ TemperatureMixin,
35
+ TopPMixin,
36
+ ThinkingMixin,
37
+ name="openai"):
28
38
  """An OpenAI LLM provider to be used with an LLM client."""
29
39
 
30
40
  model_config = ConfigDict(protected_namespaces=(), extra="allow")
@@ -34,13 +44,11 @@ class OpenAIModelConfig(LLMBaseConfig, RetryMixin, name="openai"):
34
44
  model_name: str = Field(validation_alias=AliasChoices("model_name", "model"),
35
45
  serialization_alias="model",
36
46
  description="The OpenAI hosted model name.")
37
- temperature: float = Field(default=0.0, description="Sampling temperature in [0, 1].")
38
- top_p: float = Field(default=1.0, description="Top-p for distribution sampling.")
39
47
  seed: int | None = Field(default=None, description="Random seed to set for generation.")
40
48
  max_retries: int = Field(default=10, description="The max number of retries for the request.")
41
49
 
42
50
 
43
51
  @register_llm_provider(config_type=OpenAIModelConfig)
44
- async def openai_llm(config: OpenAIModelConfig, builder: Builder):
52
+ async def openai_llm(config: OpenAIModelConfig, _builder: Builder):
45
53
 
46
54
  yield LLMProviderInfo(config=config, description="An OpenAI model for use with an LLM client.")
nat/llm/register.py CHANGED
@@ -13,11 +13,15 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- # pylint: disable=unused-import
17
16
  # flake8: noqa
18
17
  # isort:skip_file
18
+ """Register LLM providers via import side effects.
19
19
 
20
+ This module is imported by the NeMo Agent Toolkit runtime to ensure providers are registered and discoverable.
21
+ """
20
22
  # Import any providers which need to be automatically registered here
21
23
  from . import aws_bedrock_llm
24
+ from . import azure_openai_llm
25
+ from . import litellm_llm
22
26
  from . import nim_llm
23
27
  from . import openai_llm
@@ -72,9 +72,8 @@ class EnvConfigValue(ABC):
72
72
  f"{message} Try passing a value to the constructor, or setting the `{self.__class__._ENV_KEY}` "
73
73
  "environment variable.")
74
74
 
75
- else:
76
- if not self.__class__._ALLOW_NONE and value is None:
77
- raise ValueError("value must not be none")
75
+ elif not self.__class__._ALLOW_NONE and value is None:
76
+ raise ValueError("value must not be none")
78
77
 
79
78
  assert isinstance(value, str) or value is None
80
79
 
@@ -0,0 +1,215 @@
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 functools
17
+ import inspect
18
+ import logging
19
+ import types
20
+ from abc import abstractmethod
21
+ from collections.abc import AsyncGenerator
22
+ from collections.abc import Callable
23
+ from collections.abc import Iterable
24
+ from dataclasses import dataclass
25
+ from typing import Any
26
+ from typing import TypeVar
27
+
28
+ ModelType = TypeVar("ModelType")
29
+ MessagesType = TypeVar("MessagesType")
30
+
31
+ logger = logging.getLogger(__name__)
32
+
33
+
34
+ class FunctionArgumentWrapper:
35
+ """
36
+ Wrapper for the arguments and keyword arguments of a function.
37
+
38
+ The arguments and keyword arguments are stored in the args and kwargs attributes, respectively.
39
+ """
40
+
41
+ def __init__(self, *args: Any, **kwargs: Any):
42
+ """
43
+ Initialize the FunctionArgumentWrapper.
44
+
45
+ Args:
46
+ args: The arguments to the function.
47
+ kwargs: The keyword arguments to the function.
48
+ """
49
+ self.args = args
50
+ self.kwargs = kwargs
51
+
52
+ def __repr__(self) -> str:
53
+ return f"FunctionArgumentWrapper(args={self.args}, kwargs={self.kwargs})"
54
+
55
+
56
+ @dataclass
57
+ class BaseThinkingInjector:
58
+ """
59
+ Base class for thinking injectors.
60
+
61
+ Args:
62
+ system_prompt: The system prompt to inject.
63
+ function_names: The function names to inject the system prompt into.
64
+ """
65
+
66
+ system_prompt: str
67
+ function_names: list[str]
68
+
69
+ @abstractmethod
70
+ def inject(self, *args, **kwargs) -> FunctionArgumentWrapper:
71
+ """
72
+ Inject the system prompt into the arguments.
73
+
74
+ Args:
75
+ args: The arguments to inject the system prompt into.
76
+ kwargs: The keyword arguments to inject the system prompt into.
77
+
78
+ Returns:
79
+ FunctionArgumentWrapper: An object that contains the transformed args and kwargs.
80
+ """
81
+ pass
82
+
83
+
84
+ def _make_thinking_decorator(injector: BaseThinkingInjector):
85
+
86
+ def decorate(fn: Callable[..., Any]) -> Callable[..., Any]:
87
+
88
+ async def _call_async(obj: object, *call_args, **call_kwargs) -> Any:
89
+ new_args = injector.inject(*call_args, **call_kwargs)
90
+ return await fn(obj, *new_args.args, **new_args.kwargs)
91
+
92
+ async def _agen(obj: object, *call_args, **call_kwargs) -> AsyncGenerator[Any, None]:
93
+ new_args = injector.inject(*call_args, **call_kwargs)
94
+ async for item in fn(obj, *new_args.args, **new_args.kwargs):
95
+ yield item
96
+
97
+ def _gen(obj: object, *call_args, **call_kwargs) -> Iterable[Any]:
98
+ new_args = injector.inject(*call_args, **call_kwargs)
99
+ yield from fn(obj, *new_args.args, **new_args.kwargs)
100
+ return
101
+
102
+ def _sync(obj: object, *call_args, **call_kwargs) -> Any:
103
+ new_args = injector.inject(*call_args, **call_kwargs)
104
+ return fn(obj, *new_args.args, **new_args.kwargs)
105
+
106
+ # Decide which wrapper to return
107
+ if inspect.iscoroutinefunction(fn):
108
+ wrapper = _call_async
109
+ elif inspect.isasyncgenfunction(fn):
110
+ wrapper = _agen
111
+ elif inspect.isgeneratorfunction(fn):
112
+ wrapper = _gen
113
+ else:
114
+ wrapper = _sync
115
+
116
+ return functools.wraps(fn)(wrapper)
117
+
118
+ return decorate
119
+
120
+
121
+ def patch_with_thinking(obj: ModelType, injector: BaseThinkingInjector) -> ModelType:
122
+ """
123
+ Patch the given object with a decorator that injects a system prompt into the supplied messages.
124
+ There is an assumption that the first non-object argument is the messages.
125
+
126
+ Args:
127
+ obj: The object to patch.
128
+ injector: The injector to use.
129
+
130
+ Returns:
131
+ The patched object.
132
+
133
+ Examples:
134
+ >>> from nat.llm.utils.thinking import BaseThinkingInjector
135
+ >>> from nat.llm.utils.thinking import FunctionArgumentWrapper
136
+ >>> from nat.llm.utils.thinking import patch_with_thinking
137
+ >>>
138
+ >>> class MockClass:
139
+ ... def sync_method(self, *args, **kwargs):
140
+ ... return (args, kwargs)
141
+ ...
142
+ >>> mock_obj_1 = MockClass()
143
+ >>> class AddThinking(BaseThinkingInjector):
144
+ ... def inject(self, x: str, *args, **kwargs) -> FunctionArgumentWrapper:
145
+ ... return FunctionArgumentWrapper(("thinking " + x), *args, **kwargs)
146
+ >>>
147
+ >>> patched_obj = patch_with_thinking(mock_obj_1, AddThinking(
148
+ ... system_prompt="thinking",
149
+ ... function_names=["sync_method"],
150
+ ... ))
151
+ >>> patched_obj.sync_method("test", 1, 2, 3, foo="bar")
152
+ (('thinking test', 1, 2, 3), {'foo': 'bar'})
153
+ >>>
154
+ >>> mock_obj_2 = MockClass()
155
+ >>> class AddThinkingWithArgs(BaseThinkingInjector):
156
+ ... def inject(self, *args, **kwargs) -> FunctionArgumentWrapper:
157
+ ... return FunctionArgumentWrapper("thinking", *args, **kwargs)
158
+ >>>
159
+ >>> patched_obj = patch_with_thinking(mock_obj_2, AddThinkingWithArgs(
160
+ ... system_prompt="thinking",
161
+ ... function_names=["sync_method"],
162
+ ... ))
163
+ >>> patched_obj.sync_method("test", 1, 2, 3, foo="bar")
164
+ (('thinking', 'test', 1, 2, 3), {'foo': 'bar'})
165
+ >>>
166
+ >>> mock_obj_3 = MockClass()
167
+ >>> class AddThinkingWithKwargs(BaseThinkingInjector):
168
+ ... def inject(self, *args, **kwargs) -> FunctionArgumentWrapper:
169
+ ... return FunctionArgumentWrapper(*args, thinking=True, **kwargs)
170
+ >>>
171
+ >>> patched_obj = patch_with_thinking(mock_obj_3, AddThinkingWithKwargs(
172
+ ... system_prompt="thinking",
173
+ ... function_names=["sync_method"],
174
+ ... ))
175
+ >>> patched_obj.sync_method("test", 1, 2, 3, foo="bar")
176
+ (('test', 1, 2, 3), {'thinking': True, 'foo': 'bar'})
177
+ """
178
+
179
+ decorator = _make_thinking_decorator(injector)
180
+
181
+ cls = obj if inspect.isclass(obj) else type(obj)
182
+ cls_name = getattr(cls, "__name__", str(cls))
183
+
184
+ for name, _ in inspect.getmembers(cls, callable):
185
+ if name not in injector.function_names:
186
+ continue
187
+
188
+ descriptor = inspect.getattr_static(cls, name)
189
+ original = descriptor.__func__ if isinstance(descriptor, types.MethodType) else descriptor
190
+ wrapped = decorator(original)
191
+
192
+ try: # instance‑level first
193
+ if not inspect.isclass(obj):
194
+ object.__setattr__(obj, name, types.MethodType(wrapped, obj))
195
+ continue
196
+ except Exception as exc:
197
+ logger.info(
198
+ "Instance‑level patch failed for %s.%s (%s); "
199
+ "falling back to class‑level patch.",
200
+ cls_name,
201
+ name,
202
+ exc,
203
+ )
204
+
205
+ try: # class‑level fallback
206
+ setattr(cls, name, wrapped)
207
+ except Exception as exc:
208
+ logger.info(
209
+ "Cannot patch method %s.%s with thinking: %s",
210
+ cls_name,
211
+ name,
212
+ exc,
213
+ )
214
+
215
+ return obj
nat/meta/pypi.md CHANGED
@@ -23,19 +23,19 @@ NeMo Agent toolkit is a flexible library designed to seamlessly integrate your e
23
23
 
24
24
  ## Key Features
25
25
 
26
- - [**Framework Agnostic:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/extend/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
27
- - [**Reusability:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/extend/sharing-components.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
28
- - [**Rapid Development:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/tutorials/index.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
29
- - [**Profiling:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
30
- - [**Observability:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/observe/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool, with examples using [Phoenix](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/observe/observe-workflow-with-phoenix.html) and [W&B Weave](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/observe/observe-workflow-with-weave.html).
31
- - [**Evaluation System:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
32
- - [**User Interface:**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/quick-start/launching-ui.html) Use the NeMo Agent toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
33
- - [**MCP Compatibility**](https://docs.nvidia.com/nemo/agent-toolkit/1.2/workflows/mcp/mcp-client.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as NeMo Agent toolkit functions.
26
+ - [**Framework Agnostic:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/extend/plugins.html) Works with any agentic framework, so you can use your current technology stack without replatforming.
27
+ - [**Reusability:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/extend/sharing-components.html) Every agent, tool, or workflow can be combined and repurposed, allowing developers to leverage existing work in new scenarios.
28
+ - [**Rapid Development:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/tutorials/index.html) Start with a pre-built agent, tool, or workflow, and customize it to your needs.
29
+ - [**Profiling:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/profiler.html) Profile entire workflows down to the tool and agent level, track input/output tokens and timings, and identify bottlenecks.
30
+ - [**Observability:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/observe/observe-workflow-with-phoenix.html) Monitor and debug your workflows with any OpenTelemetry-compatible observability tool, with examples using [Phoenix](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/observe/observe-workflow-with-phoenix.html) and [W&B Weave](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/observe/observe-workflow-with-weave.html).
31
+ - [**Evaluation System:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/evaluate.html) Validate and maintain accuracy of agentic workflows with built-in evaluation tools.
32
+ - [**User Interface:**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/quick-start/launching-ui.html) Use the NeMo Agent toolkit UI chat interface to interact with your agents, visualize output, and debug workflows.
33
+ - [**MCP Compatibility**](https://docs.nvidia.com/nemo/agent-toolkit/1.3/workflows/mcp/mcp-client.html) Compatible with Model Context Protocol (MCP), allowing tools served by MCP Servers to be used as NeMo Agent toolkit functions.
34
34
 
35
35
  With NeMo Agent toolkit, you can move quickly, experiment freely, and ensure reliability across all your agent-driven projects.
36
36
 
37
37
  ## Links
38
- * [Documentation](https://docs.nvidia.com/nemo/agent-toolkit/1.2/index.html): Explore the full documentation for NeMo Agent toolkit.
38
+ * [Documentation](https://docs.nvidia.com/nemo/agent-toolkit/1.3/index.html): Explore the full documentation for NeMo Agent toolkit.
39
39
 
40
40
  ## First time user?
41
41
  If this is your first time using NeMo Agent toolkit, it is recommended to install the latest version from the [source repository](https://github.com/NVIDIA/NeMo-Agent-Toolkit?tab=readme-ov-file#quick-start) on GitHub. This package is intended for users who are familiar with NeMo Agent toolkit applications and need to add NeMo Agent toolkit as a dependency to their project.
@@ -13,7 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- # pylint: disable=unused-import
17
16
  # flake8: noqa
18
17
  # isort:skip_file
19
18
 
@@ -357,7 +357,7 @@ class BaseExporter(Exporter):
357
357
  except Exception as e:
358
358
  logger.warning("Error while canceling task %s: %s", task.get_name(), e)
359
359
 
360
- async def _wait_for_tasks(self, timeout: float = 5.0):
360
+ async def wait_for_tasks(self, timeout: float = 5.0):
361
361
  """Wait for all tracked tasks to complete with a timeout.
362
362
 
363
363
  Note: This method is NOT called during normal stop() operation for performance.
@@ -372,10 +372,10 @@ class BaseExporter(Exporter):
372
372
  try:
373
373
  # Wait for all tasks to complete with a timeout
374
374
  await asyncio.wait_for(asyncio.gather(*self._tasks, return_exceptions=True), timeout=timeout)
375
- except asyncio.TimeoutError:
375
+ except TimeoutError:
376
376
  logger.warning("%s: Some tasks did not complete within %s seconds", self.name, timeout)
377
377
  except Exception as e:
378
- logger.error("%s: Error while waiting for tasks: %s", self.name, e, exc_info=True)
378
+ logger.exception("%s: Error while waiting for tasks: %s", self.name, e)
379
379
 
380
380
  @override
381
381
  async def stop(self):
@@ -24,7 +24,7 @@ from nat.observability.processor.intermediate_step_serializer import Intermediat
24
24
  logger = logging.getLogger(__name__)
25
25
 
26
26
 
27
- class FileExporter(FileExportMixin, RawExporter[IntermediateStep, str]): # pylint: disable=R0901
27
+ class FileExporter(FileExportMixin, RawExporter[IntermediateStep, str]):
28
28
  """A File exporter that exports telemetry traces to a local file."""
29
29
 
30
30
  def __init__(self, context_state: ContextState | None = None, **file_kwargs):