nvidia-nat 1.1.0a20251020__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 (480) hide show
  1. aiq/__init__.py +66 -0
  2. nat/agent/__init__.py +0 -0
  3. nat/agent/base.py +265 -0
  4. nat/agent/dual_node.py +72 -0
  5. nat/agent/prompt_optimizer/__init__.py +0 -0
  6. nat/agent/prompt_optimizer/prompt.py +68 -0
  7. nat/agent/prompt_optimizer/register.py +149 -0
  8. nat/agent/react_agent/__init__.py +0 -0
  9. nat/agent/react_agent/agent.py +394 -0
  10. nat/agent/react_agent/output_parser.py +104 -0
  11. nat/agent/react_agent/prompt.py +44 -0
  12. nat/agent/react_agent/register.py +168 -0
  13. nat/agent/reasoning_agent/__init__.py +0 -0
  14. nat/agent/reasoning_agent/reasoning_agent.py +227 -0
  15. nat/agent/register.py +23 -0
  16. nat/agent/rewoo_agent/__init__.py +0 -0
  17. nat/agent/rewoo_agent/agent.py +593 -0
  18. nat/agent/rewoo_agent/prompt.py +107 -0
  19. nat/agent/rewoo_agent/register.py +175 -0
  20. nat/agent/tool_calling_agent/__init__.py +0 -0
  21. nat/agent/tool_calling_agent/agent.py +246 -0
  22. nat/agent/tool_calling_agent/register.py +129 -0
  23. nat/authentication/__init__.py +14 -0
  24. nat/authentication/api_key/__init__.py +14 -0
  25. nat/authentication/api_key/api_key_auth_provider.py +96 -0
  26. nat/authentication/api_key/api_key_auth_provider_config.py +124 -0
  27. nat/authentication/api_key/register.py +26 -0
  28. nat/authentication/credential_validator/__init__.py +14 -0
  29. nat/authentication/credential_validator/bearer_token_validator.py +557 -0
  30. nat/authentication/exceptions/__init__.py +14 -0
  31. nat/authentication/exceptions/api_key_exceptions.py +38 -0
  32. nat/authentication/http_basic_auth/__init__.py +0 -0
  33. nat/authentication/http_basic_auth/http_basic_auth_provider.py +81 -0
  34. nat/authentication/http_basic_auth/register.py +30 -0
  35. nat/authentication/interfaces.py +96 -0
  36. nat/authentication/oauth2/__init__.py +14 -0
  37. nat/authentication/oauth2/oauth2_auth_code_flow_provider.py +140 -0
  38. nat/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +39 -0
  39. nat/authentication/oauth2/oauth2_resource_server_config.py +124 -0
  40. nat/authentication/oauth2/register.py +25 -0
  41. nat/authentication/register.py +20 -0
  42. nat/builder/__init__.py +0 -0
  43. nat/builder/builder.py +317 -0
  44. nat/builder/component_utils.py +320 -0
  45. nat/builder/context.py +321 -0
  46. nat/builder/embedder.py +24 -0
  47. nat/builder/eval_builder.py +166 -0
  48. nat/builder/evaluator.py +29 -0
  49. nat/builder/framework_enum.py +25 -0
  50. nat/builder/front_end.py +73 -0
  51. nat/builder/function.py +714 -0
  52. nat/builder/function_base.py +380 -0
  53. nat/builder/function_info.py +625 -0
  54. nat/builder/intermediate_step_manager.py +206 -0
  55. nat/builder/llm.py +25 -0
  56. nat/builder/retriever.py +25 -0
  57. nat/builder/user_interaction_manager.py +78 -0
  58. nat/builder/workflow.py +160 -0
  59. nat/builder/workflow_builder.py +1365 -0
  60. nat/cli/__init__.py +14 -0
  61. nat/cli/cli_utils/__init__.py +0 -0
  62. nat/cli/cli_utils/config_override.py +231 -0
  63. nat/cli/cli_utils/validation.py +37 -0
  64. nat/cli/commands/__init__.py +0 -0
  65. nat/cli/commands/configure/__init__.py +0 -0
  66. nat/cli/commands/configure/channel/__init__.py +0 -0
  67. nat/cli/commands/configure/channel/add.py +28 -0
  68. nat/cli/commands/configure/channel/channel.py +34 -0
  69. nat/cli/commands/configure/channel/remove.py +30 -0
  70. nat/cli/commands/configure/channel/update.py +30 -0
  71. nat/cli/commands/configure/configure.py +33 -0
  72. nat/cli/commands/evaluate.py +139 -0
  73. nat/cli/commands/info/__init__.py +14 -0
  74. nat/cli/commands/info/info.py +47 -0
  75. nat/cli/commands/info/list_channels.py +32 -0
  76. nat/cli/commands/info/list_components.py +128 -0
  77. nat/cli/commands/mcp/__init__.py +14 -0
  78. nat/cli/commands/mcp/mcp.py +986 -0
  79. nat/cli/commands/object_store/__init__.py +14 -0
  80. nat/cli/commands/object_store/object_store.py +227 -0
  81. nat/cli/commands/optimize.py +90 -0
  82. nat/cli/commands/registry/__init__.py +14 -0
  83. nat/cli/commands/registry/publish.py +88 -0
  84. nat/cli/commands/registry/pull.py +118 -0
  85. nat/cli/commands/registry/registry.py +36 -0
  86. nat/cli/commands/registry/remove.py +108 -0
  87. nat/cli/commands/registry/search.py +153 -0
  88. nat/cli/commands/sizing/__init__.py +14 -0
  89. nat/cli/commands/sizing/calc.py +297 -0
  90. nat/cli/commands/sizing/sizing.py +27 -0
  91. nat/cli/commands/start.py +257 -0
  92. nat/cli/commands/uninstall.py +81 -0
  93. nat/cli/commands/validate.py +47 -0
  94. nat/cli/commands/workflow/__init__.py +14 -0
  95. nat/cli/commands/workflow/templates/__init__.py.j2 +0 -0
  96. nat/cli/commands/workflow/templates/config.yml.j2 +17 -0
  97. nat/cli/commands/workflow/templates/pyproject.toml.j2 +25 -0
  98. nat/cli/commands/workflow/templates/register.py.j2 +4 -0
  99. nat/cli/commands/workflow/templates/workflow.py.j2 +50 -0
  100. nat/cli/commands/workflow/workflow.py +37 -0
  101. nat/cli/commands/workflow/workflow_commands.py +403 -0
  102. nat/cli/entrypoint.py +141 -0
  103. nat/cli/main.py +60 -0
  104. nat/cli/register_workflow.py +522 -0
  105. nat/cli/type_registry.py +1069 -0
  106. nat/control_flow/__init__.py +0 -0
  107. nat/control_flow/register.py +20 -0
  108. nat/control_flow/router_agent/__init__.py +0 -0
  109. nat/control_flow/router_agent/agent.py +329 -0
  110. nat/control_flow/router_agent/prompt.py +48 -0
  111. nat/control_flow/router_agent/register.py +91 -0
  112. nat/control_flow/sequential_executor.py +166 -0
  113. nat/data_models/__init__.py +14 -0
  114. nat/data_models/agent.py +34 -0
  115. nat/data_models/api_server.py +843 -0
  116. nat/data_models/authentication.py +245 -0
  117. nat/data_models/common.py +171 -0
  118. nat/data_models/component.py +60 -0
  119. nat/data_models/component_ref.py +179 -0
  120. nat/data_models/config.py +434 -0
  121. nat/data_models/dataset_handler.py +169 -0
  122. nat/data_models/discovery_metadata.py +305 -0
  123. nat/data_models/embedder.py +27 -0
  124. nat/data_models/evaluate.py +130 -0
  125. nat/data_models/evaluator.py +26 -0
  126. nat/data_models/front_end.py +26 -0
  127. nat/data_models/function.py +64 -0
  128. nat/data_models/function_dependencies.py +80 -0
  129. nat/data_models/gated_field_mixin.py +242 -0
  130. nat/data_models/interactive.py +246 -0
  131. nat/data_models/intermediate_step.py +302 -0
  132. nat/data_models/invocation_node.py +38 -0
  133. nat/data_models/llm.py +27 -0
  134. nat/data_models/logging.py +26 -0
  135. nat/data_models/memory.py +27 -0
  136. nat/data_models/object_store.py +44 -0
  137. nat/data_models/optimizable.py +119 -0
  138. nat/data_models/optimizer.py +149 -0
  139. nat/data_models/profiler.py +54 -0
  140. nat/data_models/registry_handler.py +26 -0
  141. nat/data_models/retriever.py +30 -0
  142. nat/data_models/retry_mixin.py +35 -0
  143. nat/data_models/span.py +228 -0
  144. nat/data_models/step_adaptor.py +64 -0
  145. nat/data_models/streaming.py +33 -0
  146. nat/data_models/swe_bench_model.py +54 -0
  147. nat/data_models/telemetry_exporter.py +26 -0
  148. nat/data_models/temperature_mixin.py +44 -0
  149. nat/data_models/thinking_mixin.py +86 -0
  150. nat/data_models/top_p_mixin.py +44 -0
  151. nat/data_models/ttc_strategy.py +30 -0
  152. nat/embedder/__init__.py +0 -0
  153. nat/embedder/azure_openai_embedder.py +46 -0
  154. nat/embedder/nim_embedder.py +59 -0
  155. nat/embedder/openai_embedder.py +42 -0
  156. nat/embedder/register.py +22 -0
  157. nat/eval/__init__.py +14 -0
  158. nat/eval/config.py +62 -0
  159. nat/eval/dataset_handler/__init__.py +0 -0
  160. nat/eval/dataset_handler/dataset_downloader.py +106 -0
  161. nat/eval/dataset_handler/dataset_filter.py +52 -0
  162. nat/eval/dataset_handler/dataset_handler.py +431 -0
  163. nat/eval/evaluate.py +565 -0
  164. nat/eval/evaluator/__init__.py +14 -0
  165. nat/eval/evaluator/base_evaluator.py +77 -0
  166. nat/eval/evaluator/evaluator_model.py +58 -0
  167. nat/eval/intermediate_step_adapter.py +99 -0
  168. nat/eval/rag_evaluator/__init__.py +0 -0
  169. nat/eval/rag_evaluator/evaluate.py +178 -0
  170. nat/eval/rag_evaluator/register.py +143 -0
  171. nat/eval/register.py +26 -0
  172. nat/eval/remote_workflow.py +133 -0
  173. nat/eval/runners/__init__.py +14 -0
  174. nat/eval/runners/config.py +39 -0
  175. nat/eval/runners/multi_eval_runner.py +54 -0
  176. nat/eval/runtime_evaluator/__init__.py +14 -0
  177. nat/eval/runtime_evaluator/evaluate.py +123 -0
  178. nat/eval/runtime_evaluator/register.py +100 -0
  179. nat/eval/runtime_event_subscriber.py +52 -0
  180. nat/eval/swe_bench_evaluator/__init__.py +0 -0
  181. nat/eval/swe_bench_evaluator/evaluate.py +215 -0
  182. nat/eval/swe_bench_evaluator/register.py +36 -0
  183. nat/eval/trajectory_evaluator/__init__.py +0 -0
  184. nat/eval/trajectory_evaluator/evaluate.py +75 -0
  185. nat/eval/trajectory_evaluator/register.py +40 -0
  186. nat/eval/tunable_rag_evaluator/__init__.py +0 -0
  187. nat/eval/tunable_rag_evaluator/evaluate.py +242 -0
  188. nat/eval/tunable_rag_evaluator/register.py +52 -0
  189. nat/eval/usage_stats.py +41 -0
  190. nat/eval/utils/__init__.py +0 -0
  191. nat/eval/utils/eval_trace_ctx.py +89 -0
  192. nat/eval/utils/output_uploader.py +140 -0
  193. nat/eval/utils/tqdm_position_registry.py +40 -0
  194. nat/eval/utils/weave_eval.py +193 -0
  195. nat/experimental/__init__.py +0 -0
  196. nat/experimental/decorators/__init__.py +0 -0
  197. nat/experimental/decorators/experimental_warning_decorator.py +154 -0
  198. nat/experimental/test_time_compute/__init__.py +0 -0
  199. nat/experimental/test_time_compute/editing/__init__.py +0 -0
  200. nat/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +147 -0
  201. nat/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +204 -0
  202. nat/experimental/test_time_compute/editing/motivation_aware_summarization.py +107 -0
  203. nat/experimental/test_time_compute/functions/__init__.py +0 -0
  204. nat/experimental/test_time_compute/functions/execute_score_select_function.py +105 -0
  205. nat/experimental/test_time_compute/functions/plan_select_execute_function.py +228 -0
  206. nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +205 -0
  207. nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +146 -0
  208. nat/experimental/test_time_compute/models/__init__.py +0 -0
  209. nat/experimental/test_time_compute/models/editor_config.py +132 -0
  210. nat/experimental/test_time_compute/models/scoring_config.py +112 -0
  211. nat/experimental/test_time_compute/models/search_config.py +120 -0
  212. nat/experimental/test_time_compute/models/selection_config.py +154 -0
  213. nat/experimental/test_time_compute/models/stage_enums.py +43 -0
  214. nat/experimental/test_time_compute/models/strategy_base.py +67 -0
  215. nat/experimental/test_time_compute/models/tool_use_config.py +41 -0
  216. nat/experimental/test_time_compute/models/ttc_item.py +48 -0
  217. nat/experimental/test_time_compute/register.py +35 -0
  218. nat/experimental/test_time_compute/scoring/__init__.py +0 -0
  219. nat/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +168 -0
  220. nat/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +168 -0
  221. nat/experimental/test_time_compute/scoring/motivation_aware_scorer.py +111 -0
  222. nat/experimental/test_time_compute/search/__init__.py +0 -0
  223. nat/experimental/test_time_compute/search/multi_llm_planner.py +128 -0
  224. nat/experimental/test_time_compute/search/multi_query_retrieval_search.py +122 -0
  225. nat/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +128 -0
  226. nat/experimental/test_time_compute/selection/__init__.py +0 -0
  227. nat/experimental/test_time_compute/selection/best_of_n_selector.py +63 -0
  228. nat/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +131 -0
  229. nat/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +157 -0
  230. nat/experimental/test_time_compute/selection/llm_based_plan_selector.py +128 -0
  231. nat/experimental/test_time_compute/selection/threshold_selector.py +58 -0
  232. nat/front_ends/__init__.py +14 -0
  233. nat/front_ends/console/__init__.py +14 -0
  234. nat/front_ends/console/authentication_flow_handler.py +285 -0
  235. nat/front_ends/console/console_front_end_config.py +32 -0
  236. nat/front_ends/console/console_front_end_plugin.py +108 -0
  237. nat/front_ends/console/register.py +25 -0
  238. nat/front_ends/cron/__init__.py +14 -0
  239. nat/front_ends/fastapi/__init__.py +14 -0
  240. nat/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
  241. nat/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +27 -0
  242. nat/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +142 -0
  243. nat/front_ends/fastapi/dask_client_mixin.py +65 -0
  244. nat/front_ends/fastapi/fastapi_front_end_config.py +272 -0
  245. nat/front_ends/fastapi/fastapi_front_end_controller.py +68 -0
  246. nat/front_ends/fastapi/fastapi_front_end_plugin.py +247 -0
  247. nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py +1257 -0
  248. nat/front_ends/fastapi/html_snippets/__init__.py +14 -0
  249. nat/front_ends/fastapi/html_snippets/auth_code_grant_success.py +35 -0
  250. nat/front_ends/fastapi/intermediate_steps_subscriber.py +80 -0
  251. nat/front_ends/fastapi/job_store.py +602 -0
  252. nat/front_ends/fastapi/main.py +64 -0
  253. nat/front_ends/fastapi/message_handler.py +344 -0
  254. nat/front_ends/fastapi/message_validator.py +351 -0
  255. nat/front_ends/fastapi/register.py +25 -0
  256. nat/front_ends/fastapi/response_helpers.py +195 -0
  257. nat/front_ends/fastapi/step_adaptor.py +319 -0
  258. nat/front_ends/fastapi/utils.py +57 -0
  259. nat/front_ends/mcp/__init__.py +14 -0
  260. nat/front_ends/mcp/introspection_token_verifier.py +73 -0
  261. nat/front_ends/mcp/mcp_front_end_config.py +90 -0
  262. nat/front_ends/mcp/mcp_front_end_plugin.py +113 -0
  263. nat/front_ends/mcp/mcp_front_end_plugin_worker.py +268 -0
  264. nat/front_ends/mcp/memory_profiler.py +320 -0
  265. nat/front_ends/mcp/register.py +27 -0
  266. nat/front_ends/mcp/tool_converter.py +290 -0
  267. nat/front_ends/register.py +21 -0
  268. nat/front_ends/simple_base/__init__.py +14 -0
  269. nat/front_ends/simple_base/simple_front_end_plugin_base.py +56 -0
  270. nat/llm/__init__.py +0 -0
  271. nat/llm/aws_bedrock_llm.py +69 -0
  272. nat/llm/azure_openai_llm.py +57 -0
  273. nat/llm/litellm_llm.py +69 -0
  274. nat/llm/nim_llm.py +58 -0
  275. nat/llm/openai_llm.py +54 -0
  276. nat/llm/register.py +27 -0
  277. nat/llm/utils/__init__.py +14 -0
  278. nat/llm/utils/env_config_value.py +93 -0
  279. nat/llm/utils/error.py +17 -0
  280. nat/llm/utils/thinking.py +215 -0
  281. nat/memory/__init__.py +20 -0
  282. nat/memory/interfaces.py +183 -0
  283. nat/memory/models.py +112 -0
  284. nat/meta/pypi.md +58 -0
  285. nat/object_store/__init__.py +20 -0
  286. nat/object_store/in_memory_object_store.py +76 -0
  287. nat/object_store/interfaces.py +84 -0
  288. nat/object_store/models.py +38 -0
  289. nat/object_store/register.py +19 -0
  290. nat/observability/__init__.py +14 -0
  291. nat/observability/exporter/__init__.py +14 -0
  292. nat/observability/exporter/base_exporter.py +449 -0
  293. nat/observability/exporter/exporter.py +78 -0
  294. nat/observability/exporter/file_exporter.py +33 -0
  295. nat/observability/exporter/processing_exporter.py +550 -0
  296. nat/observability/exporter/raw_exporter.py +52 -0
  297. nat/observability/exporter/span_exporter.py +308 -0
  298. nat/observability/exporter_manager.py +335 -0
  299. nat/observability/mixin/__init__.py +14 -0
  300. nat/observability/mixin/batch_config_mixin.py +26 -0
  301. nat/observability/mixin/collector_config_mixin.py +23 -0
  302. nat/observability/mixin/file_mixin.py +288 -0
  303. nat/observability/mixin/file_mode.py +23 -0
  304. nat/observability/mixin/redaction_config_mixin.py +42 -0
  305. nat/observability/mixin/resource_conflict_mixin.py +134 -0
  306. nat/observability/mixin/serialize_mixin.py +61 -0
  307. nat/observability/mixin/tagging_config_mixin.py +62 -0
  308. nat/observability/mixin/type_introspection_mixin.py +496 -0
  309. nat/observability/processor/__init__.py +14 -0
  310. nat/observability/processor/batching_processor.py +308 -0
  311. nat/observability/processor/callback_processor.py +42 -0
  312. nat/observability/processor/falsy_batch_filter_processor.py +55 -0
  313. nat/observability/processor/intermediate_step_serializer.py +28 -0
  314. nat/observability/processor/processor.py +74 -0
  315. nat/observability/processor/processor_factory.py +70 -0
  316. nat/observability/processor/redaction/__init__.py +24 -0
  317. nat/observability/processor/redaction/contextual_redaction_processor.py +125 -0
  318. nat/observability/processor/redaction/contextual_span_redaction_processor.py +66 -0
  319. nat/observability/processor/redaction/redaction_processor.py +177 -0
  320. nat/observability/processor/redaction/span_header_redaction_processor.py +92 -0
  321. nat/observability/processor/span_tagging_processor.py +68 -0
  322. nat/observability/register.py +114 -0
  323. nat/observability/utils/__init__.py +14 -0
  324. nat/observability/utils/dict_utils.py +236 -0
  325. nat/observability/utils/time_utils.py +31 -0
  326. nat/plugins/.namespace +1 -0
  327. nat/profiler/__init__.py +0 -0
  328. nat/profiler/calc/__init__.py +14 -0
  329. nat/profiler/calc/calc_runner.py +626 -0
  330. nat/profiler/calc/calculations.py +288 -0
  331. nat/profiler/calc/data_models.py +188 -0
  332. nat/profiler/calc/plot.py +345 -0
  333. nat/profiler/callbacks/__init__.py +0 -0
  334. nat/profiler/callbacks/agno_callback_handler.py +295 -0
  335. nat/profiler/callbacks/base_callback_class.py +20 -0
  336. nat/profiler/callbacks/langchain_callback_handler.py +297 -0
  337. nat/profiler/callbacks/llama_index_callback_handler.py +205 -0
  338. nat/profiler/callbacks/semantic_kernel_callback_handler.py +238 -0
  339. nat/profiler/callbacks/token_usage_base_model.py +27 -0
  340. nat/profiler/data_frame_row.py +51 -0
  341. nat/profiler/data_models.py +24 -0
  342. nat/profiler/decorators/__init__.py +0 -0
  343. nat/profiler/decorators/framework_wrapper.py +180 -0
  344. nat/profiler/decorators/function_tracking.py +411 -0
  345. nat/profiler/forecasting/__init__.py +0 -0
  346. nat/profiler/forecasting/config.py +18 -0
  347. nat/profiler/forecasting/model_trainer.py +75 -0
  348. nat/profiler/forecasting/models/__init__.py +22 -0
  349. nat/profiler/forecasting/models/forecasting_base_model.py +42 -0
  350. nat/profiler/forecasting/models/linear_model.py +197 -0
  351. nat/profiler/forecasting/models/random_forest_regressor.py +269 -0
  352. nat/profiler/inference_metrics_model.py +28 -0
  353. nat/profiler/inference_optimization/__init__.py +0 -0
  354. nat/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
  355. nat/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +460 -0
  356. nat/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +258 -0
  357. nat/profiler/inference_optimization/data_models.py +386 -0
  358. nat/profiler/inference_optimization/experimental/__init__.py +0 -0
  359. nat/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +468 -0
  360. nat/profiler/inference_optimization/experimental/prefix_span_analysis.py +404 -0
  361. nat/profiler/inference_optimization/llm_metrics.py +212 -0
  362. nat/profiler/inference_optimization/prompt_caching.py +163 -0
  363. nat/profiler/inference_optimization/token_uniqueness.py +107 -0
  364. nat/profiler/inference_optimization/workflow_runtimes.py +72 -0
  365. nat/profiler/intermediate_property_adapter.py +102 -0
  366. nat/profiler/parameter_optimization/__init__.py +0 -0
  367. nat/profiler/parameter_optimization/optimizable_utils.py +93 -0
  368. nat/profiler/parameter_optimization/optimizer_runtime.py +67 -0
  369. nat/profiler/parameter_optimization/parameter_optimizer.py +153 -0
  370. nat/profiler/parameter_optimization/parameter_selection.py +107 -0
  371. nat/profiler/parameter_optimization/pareto_visualizer.py +380 -0
  372. nat/profiler/parameter_optimization/prompt_optimizer.py +384 -0
  373. nat/profiler/parameter_optimization/update_helpers.py +66 -0
  374. nat/profiler/profile_runner.py +478 -0
  375. nat/profiler/utils.py +186 -0
  376. nat/registry_handlers/__init__.py +0 -0
  377. nat/registry_handlers/local/__init__.py +0 -0
  378. nat/registry_handlers/local/local_handler.py +176 -0
  379. nat/registry_handlers/local/register_local.py +37 -0
  380. nat/registry_handlers/metadata_factory.py +60 -0
  381. nat/registry_handlers/package_utils.py +570 -0
  382. nat/registry_handlers/pypi/__init__.py +0 -0
  383. nat/registry_handlers/pypi/pypi_handler.py +248 -0
  384. nat/registry_handlers/pypi/register_pypi.py +40 -0
  385. nat/registry_handlers/register.py +20 -0
  386. nat/registry_handlers/registry_handler_base.py +157 -0
  387. nat/registry_handlers/rest/__init__.py +0 -0
  388. nat/registry_handlers/rest/register_rest.py +56 -0
  389. nat/registry_handlers/rest/rest_handler.py +236 -0
  390. nat/registry_handlers/schemas/__init__.py +0 -0
  391. nat/registry_handlers/schemas/headers.py +42 -0
  392. nat/registry_handlers/schemas/package.py +68 -0
  393. nat/registry_handlers/schemas/publish.py +68 -0
  394. nat/registry_handlers/schemas/pull.py +82 -0
  395. nat/registry_handlers/schemas/remove.py +36 -0
  396. nat/registry_handlers/schemas/search.py +91 -0
  397. nat/registry_handlers/schemas/status.py +47 -0
  398. nat/retriever/__init__.py +0 -0
  399. nat/retriever/interface.py +41 -0
  400. nat/retriever/milvus/__init__.py +14 -0
  401. nat/retriever/milvus/register.py +81 -0
  402. nat/retriever/milvus/retriever.py +228 -0
  403. nat/retriever/models.py +77 -0
  404. nat/retriever/nemo_retriever/__init__.py +14 -0
  405. nat/retriever/nemo_retriever/register.py +60 -0
  406. nat/retriever/nemo_retriever/retriever.py +190 -0
  407. nat/retriever/register.py +21 -0
  408. nat/runtime/__init__.py +14 -0
  409. nat/runtime/loader.py +220 -0
  410. nat/runtime/runner.py +292 -0
  411. nat/runtime/session.py +223 -0
  412. nat/runtime/user_metadata.py +130 -0
  413. nat/settings/__init__.py +0 -0
  414. nat/settings/global_settings.py +329 -0
  415. nat/test/.namespace +1 -0
  416. nat/tool/__init__.py +0 -0
  417. nat/tool/chat_completion.py +77 -0
  418. nat/tool/code_execution/README.md +151 -0
  419. nat/tool/code_execution/__init__.py +0 -0
  420. nat/tool/code_execution/code_sandbox.py +267 -0
  421. nat/tool/code_execution/local_sandbox/.gitignore +1 -0
  422. nat/tool/code_execution/local_sandbox/Dockerfile.sandbox +60 -0
  423. nat/tool/code_execution/local_sandbox/__init__.py +13 -0
  424. nat/tool/code_execution/local_sandbox/local_sandbox_server.py +198 -0
  425. nat/tool/code_execution/local_sandbox/sandbox.requirements.txt +6 -0
  426. nat/tool/code_execution/local_sandbox/start_local_sandbox.sh +50 -0
  427. nat/tool/code_execution/register.py +74 -0
  428. nat/tool/code_execution/test_code_execution_sandbox.py +414 -0
  429. nat/tool/code_execution/utils.py +100 -0
  430. nat/tool/datetime_tools.py +82 -0
  431. nat/tool/document_search.py +141 -0
  432. nat/tool/github_tools.py +450 -0
  433. nat/tool/memory_tools/__init__.py +0 -0
  434. nat/tool/memory_tools/add_memory_tool.py +79 -0
  435. nat/tool/memory_tools/delete_memory_tool.py +66 -0
  436. nat/tool/memory_tools/get_memory_tool.py +72 -0
  437. nat/tool/nvidia_rag.py +95 -0
  438. nat/tool/register.py +31 -0
  439. nat/tool/retriever.py +95 -0
  440. nat/tool/server_tools.py +66 -0
  441. nat/utils/__init__.py +0 -0
  442. nat/utils/callable_utils.py +70 -0
  443. nat/utils/data_models/__init__.py +0 -0
  444. nat/utils/data_models/schema_validator.py +58 -0
  445. nat/utils/debugging_utils.py +43 -0
  446. nat/utils/decorators.py +210 -0
  447. nat/utils/dump_distro_mapping.py +32 -0
  448. nat/utils/exception_handlers/__init__.py +0 -0
  449. nat/utils/exception_handlers/automatic_retries.py +342 -0
  450. nat/utils/exception_handlers/schemas.py +114 -0
  451. nat/utils/io/__init__.py +0 -0
  452. nat/utils/io/model_processing.py +28 -0
  453. nat/utils/io/yaml_tools.py +119 -0
  454. nat/utils/log_levels.py +25 -0
  455. nat/utils/log_utils.py +37 -0
  456. nat/utils/metadata_utils.py +74 -0
  457. nat/utils/optional_imports.py +142 -0
  458. nat/utils/producer_consumer_queue.py +178 -0
  459. nat/utils/reactive/__init__.py +0 -0
  460. nat/utils/reactive/base/__init__.py +0 -0
  461. nat/utils/reactive/base/observable_base.py +65 -0
  462. nat/utils/reactive/base/observer_base.py +55 -0
  463. nat/utils/reactive/base/subject_base.py +79 -0
  464. nat/utils/reactive/observable.py +59 -0
  465. nat/utils/reactive/observer.py +76 -0
  466. nat/utils/reactive/subject.py +131 -0
  467. nat/utils/reactive/subscription.py +49 -0
  468. nat/utils/settings/__init__.py +0 -0
  469. nat/utils/settings/global_settings.py +195 -0
  470. nat/utils/string_utils.py +38 -0
  471. nat/utils/type_converter.py +299 -0
  472. nat/utils/type_utils.py +488 -0
  473. nat/utils/url_utils.py +27 -0
  474. nvidia_nat-1.1.0a20251020.dist-info/METADATA +195 -0
  475. nvidia_nat-1.1.0a20251020.dist-info/RECORD +480 -0
  476. nvidia_nat-1.1.0a20251020.dist-info/WHEEL +5 -0
  477. nvidia_nat-1.1.0a20251020.dist-info/entry_points.txt +22 -0
  478. nvidia_nat-1.1.0a20251020.dist-info/licenses/LICENSE-3rd-party.txt +5478 -0
  479. nvidia_nat-1.1.0a20251020.dist-info/licenses/LICENSE.md +201 -0
  480. nvidia_nat-1.1.0a20251020.dist-info/top_level.txt +2 -0
@@ -0,0 +1,403 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import logging
17
+ import os.path
18
+ import shutil
19
+ import subprocess
20
+ from pathlib import Path
21
+ from urllib.parse import urlparse
22
+
23
+ import click
24
+ from jinja2 import Environment
25
+ from jinja2 import FileSystemLoader
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ def _get_nat_version() -> str | None:
31
+ """
32
+ Get the current NAT version.
33
+
34
+ Returns:
35
+ str: The NAT version intended for use in a dependency string.
36
+ None: If the NAT version is not found.
37
+ """
38
+ from nat.cli.entrypoint import get_version
39
+
40
+ current_version = get_version()
41
+ if current_version == "unknown":
42
+ return None
43
+
44
+ version_parts = current_version.split(".")
45
+ if len(version_parts) < 3:
46
+ # If the version somehow doesn't have three parts, return the full version
47
+ return current_version
48
+
49
+ patch = version_parts[2]
50
+ try:
51
+ # If the patch is a number, keep only the major and minor parts
52
+ # Useful for stable releases and adheres to semantic versioning
53
+ _ = int(patch)
54
+ digits_to_keep = 2
55
+ except ValueError:
56
+ # If the patch is not a number, keep all three digits
57
+ # Useful for pre-release versions (and nightly builds)
58
+ digits_to_keep = 3
59
+
60
+ return ".".join(version_parts[:digits_to_keep])
61
+
62
+
63
+ def _is_nat_version_prerelease() -> bool:
64
+ """
65
+ Check if the NAT version is a prerelease.
66
+ """
67
+ version = _get_nat_version()
68
+ if version is None:
69
+ return False
70
+
71
+ return len(version.split(".")) >= 3
72
+
73
+
74
+ def _get_nat_dependency(versioned: bool = True) -> str:
75
+ """
76
+ Get the NAT dependency string with version.
77
+
78
+ Args:
79
+ versioned: Whether to include the version in the dependency string
80
+
81
+ Returns:
82
+ str: The dependency string to use in pyproject.toml
83
+ """
84
+ # Assume the default dependency is LangChain/LangGraph
85
+ dependency = "nvidia-nat[langchain]"
86
+
87
+ if not versioned:
88
+ logger.debug("Using unversioned NAT dependency: %s", dependency)
89
+ return dependency
90
+
91
+ version = _get_nat_version()
92
+ if version is None:
93
+ logger.debug("Could not detect NAT version, using unversioned dependency: %s", dependency)
94
+ return dependency
95
+
96
+ dependency += f"~={version}"
97
+ logger.debug("Using NAT dependency: %s", dependency)
98
+ return dependency
99
+
100
+
101
+ class PackageError(Exception):
102
+ pass
103
+
104
+
105
+ def get_repo_root():
106
+ return find_package_root("nvidia-nat")
107
+
108
+
109
+ def _get_module_name(workflow_name: str):
110
+ return workflow_name.replace("-", "_")
111
+
112
+
113
+ def _generate_valid_classname(class_name: str):
114
+ return class_name.replace('_', ' ').replace('-', ' ').title().replace(' ', '')
115
+
116
+
117
+ def find_package_root(package_name: str) -> Path | None:
118
+ """
119
+ Find the root directory for a python package installed with the "editable" option.
120
+
121
+ Args:
122
+ package_name: The python package name as it appears when importing it into a python script
123
+
124
+ Returns:
125
+ Posix path pointing to the package root
126
+ """
127
+ import json
128
+ from importlib.metadata import Distribution
129
+ from importlib.metadata import PackageNotFoundError
130
+
131
+ try:
132
+ dist_info = Distribution.from_name(package_name)
133
+ direct_url = dist_info.read_text("direct_url.json")
134
+ if not direct_url:
135
+ return None
136
+
137
+ try:
138
+ info = json.loads(direct_url)
139
+ except json.JSONDecodeError:
140
+ logger.exception("Malformed direct_url.json for package: %s", package_name)
141
+ return None
142
+
143
+ if not info.get("dir_info", {}).get("editable"):
144
+ return None
145
+
146
+ # Parse URL
147
+ url = info.get("url", "")
148
+ parsed_url = urlparse(url)
149
+
150
+ if parsed_url.scheme != "file":
151
+ logger.error("Invalid URL scheme in direct_url.json: %s", url)
152
+ return None
153
+
154
+ package_root = Path(parsed_url.path).resolve()
155
+
156
+ # Ensure the path exists and is within an allowed base directory
157
+ if not package_root.exists() or not package_root.is_dir():
158
+ logger.error("Package root does not exist: %s", package_root)
159
+ return None
160
+
161
+ return package_root
162
+
163
+ except TypeError:
164
+ return None
165
+
166
+ except PackageNotFoundError as e:
167
+ raise PackageError(f"Package {package_name} is not installed") from e
168
+
169
+
170
+ def get_workflow_path_from_name(workflow_name: str):
171
+ """
172
+ Look up the location of an installed NAT workflow and retrieve the root directory of the installed workflow.
173
+
174
+ Args:
175
+ workflow_name: The name of the workflow.
176
+
177
+ Returns:
178
+ Path object for the workflow's root directory.
179
+ """
180
+ # Get the module name as a valid package name.
181
+ try:
182
+ module_name = _get_module_name(workflow_name)
183
+ package_root = find_package_root(module_name)
184
+ return package_root
185
+
186
+ except PackageError as e:
187
+ logger.info("Unable to get the directory path for %s: %s", workflow_name, e)
188
+ return None
189
+
190
+
191
+ @click.command()
192
+ @click.argument('workflow_name')
193
+ @click.option('--install/--no-install', default=True, help="Whether to install the workflow package immediately.")
194
+ @click.option(
195
+ "--workflow-dir",
196
+ default=".",
197
+ help="Output directory for saving the created workflow. A new folder with the workflow name will be created "
198
+ "within. Defaults to the present working directory.")
199
+ @click.option(
200
+ "--description",
201
+ default="NAT function template. Please update the description.",
202
+ help="""A description of the component being created. Will be used to populate the docstring and will describe the
203
+ component when inspecting installed components using 'nat info component'""")
204
+ def create_command(workflow_name: str, install: bool, workflow_dir: str, description: str):
205
+ """
206
+ Create a new NAT workflow using templates.
207
+
208
+ Args:
209
+ workflow_name (str): The name of the new workflow.
210
+ install (bool): Whether to install the workflow package immediately.
211
+ workflow_dir (str): The directory to create the workflow package.
212
+ description (str): Description to pre-popluate the workflow docstring.
213
+ """
214
+ # Fail fast with Click's standard exit code (2) for bad params.
215
+ if not workflow_name or not workflow_name.strip():
216
+ raise click.BadParameter("Workflow name cannot be empty.") # noqa: TRY003
217
+ try:
218
+ # Get the repository root
219
+ try:
220
+ repo_root = get_repo_root()
221
+ except PackageError:
222
+ repo_root = None
223
+
224
+ # Get the absolute path for the output directory
225
+ if not os.path.isabs(workflow_dir):
226
+ workflow_dir = os.path.abspath(workflow_dir)
227
+
228
+ if not os.path.exists(workflow_dir):
229
+ raise ValueError(f"Invalid workflow directory specified. {workflow_dir} does not exist.")
230
+
231
+ # Define paths
232
+ template_dir = Path(__file__).parent / 'templates'
233
+ new_workflow_dir = Path(workflow_dir) / workflow_name
234
+ package_name = _get_module_name(workflow_name)
235
+ rel_path_to_repo_root = "" if not repo_root else os.path.relpath(repo_root, new_workflow_dir)
236
+
237
+ # Check if the workflow already exists
238
+ if new_workflow_dir.exists():
239
+ click.echo(f"Workflow '{workflow_name}' already exists.")
240
+ return
241
+
242
+ base_dir = new_workflow_dir / 'src' / package_name
243
+
244
+ configs_dir = base_dir / 'configs'
245
+ data_dir = base_dir / 'data'
246
+
247
+ # Create directory structure
248
+ base_dir.mkdir(parents=True)
249
+ # Create config directory
250
+ configs_dir.mkdir(parents=True)
251
+ # Create data directory
252
+ data_dir.mkdir(parents=True)
253
+
254
+ # Initialize Jinja2 environment
255
+ env = Environment(loader=FileSystemLoader(str(template_dir)))
256
+ editable = get_repo_root() is not None
257
+
258
+ if editable:
259
+ install_cmd = ['uv', 'pip', 'install', '-e', str(new_workflow_dir)]
260
+ else:
261
+ install_cmd = ['pip', 'install', '-e', str(new_workflow_dir)]
262
+ if _is_nat_version_prerelease():
263
+ install_cmd.insert(2, "--pre")
264
+
265
+ python_safe_workflow_name = workflow_name.replace("-", "_")
266
+
267
+ # List of templates and their destinations
268
+ files_to_render = {
269
+ 'pyproject.toml.j2': new_workflow_dir / 'pyproject.toml',
270
+ 'register.py.j2': base_dir / 'register.py',
271
+ 'workflow.py.j2': base_dir / f'{python_safe_workflow_name}.py',
272
+ '__init__.py.j2': base_dir / '__init__.py',
273
+ 'config.yml.j2': configs_dir / 'config.yml',
274
+ }
275
+
276
+ # Render templates
277
+ context = {
278
+ 'editable': editable,
279
+ 'workflow_name': workflow_name,
280
+ 'python_safe_workflow_name': python_safe_workflow_name,
281
+ 'package_name': package_name,
282
+ 'rel_path_to_repo_root': rel_path_to_repo_root,
283
+ 'workflow_class_name': f"{_generate_valid_classname(workflow_name)}FunctionConfig",
284
+ 'workflow_description': description,
285
+ 'nat_dependency': _get_nat_dependency()
286
+ }
287
+
288
+ for template_name, output_path in files_to_render.items():
289
+ template = env.get_template(template_name)
290
+ content = template.render(context)
291
+ with open(output_path, 'w', encoding="utf-8") as f:
292
+ f.write(content)
293
+
294
+ # Create symlinks for config and data directories
295
+ config_dir_source = configs_dir
296
+ config_dir_link = new_workflow_dir / 'configs'
297
+ data_dir_source = data_dir
298
+ data_dir_link = new_workflow_dir / 'data'
299
+ os.symlink(config_dir_source, config_dir_link)
300
+ os.symlink(data_dir_source, data_dir_link)
301
+
302
+ if install:
303
+ # Install the new package without changing directories
304
+ click.echo(f"Installing workflow '{workflow_name}'...")
305
+ result = subprocess.run(install_cmd, capture_output=True, text=True, check=True)
306
+
307
+ if result.returncode != 0:
308
+ click.echo(f"An error occurred during installation:\n{result.stderr}")
309
+ return
310
+
311
+ click.echo(f"Workflow '{workflow_name}' installed successfully.")
312
+
313
+ click.echo(f"Workflow '{workflow_name}' created successfully in '{new_workflow_dir}'.")
314
+ except Exception as e:
315
+ logger.exception("An error occurred while creating the workflow: %s", e)
316
+ click.echo(f"An error occurred while creating the workflow: {e}")
317
+
318
+
319
+ @click.command()
320
+ @click.argument('workflow_name')
321
+ def reinstall_command(workflow_name):
322
+ """
323
+ Reinstall a NAT workflow to update dependencies and code changes.
324
+
325
+ Args:
326
+ workflow_name (str): The name of the workflow to reinstall.
327
+ """
328
+ try:
329
+ editable = get_repo_root() is not None
330
+
331
+ workflow_dir = get_workflow_path_from_name(workflow_name)
332
+ if not workflow_dir or not workflow_dir.exists():
333
+ click.echo(f"Workflow '{workflow_name}' does not exist.")
334
+ return
335
+
336
+ # Reinstall the package without changing directories
337
+ click.echo(f"Reinstalling workflow '{workflow_name}'...")
338
+ if editable:
339
+ reinstall_cmd = ['uv', 'pip', 'install', '-e', str(workflow_dir)]
340
+ else:
341
+ reinstall_cmd = ['pip', 'install', '-e', str(workflow_dir)]
342
+
343
+ result = subprocess.run(reinstall_cmd, capture_output=True, text=True, check=True)
344
+
345
+ if result.returncode != 0:
346
+ click.echo(f"An error occurred during installation:\n{result.stderr}")
347
+ return
348
+
349
+ click.echo(f"Workflow '{workflow_name}' reinstalled successfully.")
350
+ except Exception as e:
351
+ logger.exception("An error occurred while reinstalling the workflow: %s", e)
352
+ click.echo(f"An error occurred while reinstalling the workflow: {e}")
353
+
354
+
355
+ @click.command()
356
+ @click.argument('workflow_name')
357
+ def delete_command(workflow_name: str):
358
+ """
359
+ Delete a NAT workflow and uninstall its package.
360
+
361
+ Args:
362
+ workflow_name (str): The name of the workflow to delete.
363
+ """
364
+ try:
365
+ if not click.confirm(f"Are you sure you want to delete the workflow '{workflow_name}'?"):
366
+ click.echo("Workflow deletion cancelled.")
367
+ return
368
+ editable = get_repo_root() is not None
369
+
370
+ workflow_dir = get_workflow_path_from_name(workflow_name)
371
+ package_name = _get_module_name(workflow_name)
372
+
373
+ if editable:
374
+ uninstall_cmd = ['uv', 'pip', 'uninstall', package_name]
375
+ else:
376
+ uninstall_cmd = ['pip', 'uninstall', '-y', package_name]
377
+
378
+ # Uninstall the package
379
+ click.echo(f"Uninstalling workflow '{workflow_name}' package...")
380
+ result = subprocess.run(uninstall_cmd, capture_output=True, text=True, check=True)
381
+
382
+ if result.returncode != 0:
383
+ click.echo(f"An error occurred during uninstallation:\n{result.stderr}")
384
+ return
385
+ click.echo(
386
+ f"Workflow '{workflow_name}' (package '{package_name}') successfully uninstalled from python environment")
387
+
388
+ if not workflow_dir or not workflow_dir.exists():
389
+ click.echo(f"Unable to locate local files for {workflow_name}. Nothing will be deleted.")
390
+ return
391
+
392
+ # Remove the workflow directory
393
+ click.echo(f"Deleting workflow directory '{workflow_dir}'...")
394
+ shutil.rmtree(workflow_dir)
395
+
396
+ click.echo(f"Workflow '{workflow_name}' deleted successfully.")
397
+ except Exception as e:
398
+ logger.exception("An error occurred while deleting the workflow: %s", e)
399
+ click.echo(f"An error occurred while deleting the workflow: {e}")
400
+
401
+
402
+ # Compatibility aliases with previous releases
403
+ AIQPackageError = PackageError
nat/cli/entrypoint.py ADDED
@@ -0,0 +1,141 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
17
+ # SPDX-License-Identifier: LicenseRef-NvidiaProprietary
18
+ #
19
+ # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
20
+ # property and proprietary rights in and to this material, related
21
+ # documentation and any modifications thereto. Any use, reproduction,
22
+ # disclosure or distribution of this material and related documentation
23
+ # without an express license agreement from NVIDIA CORPORATION or
24
+ # its affiliates is strictly prohibited.
25
+
26
+ import logging
27
+ import sys
28
+ import time
29
+
30
+ import click
31
+ import nest_asyncio
32
+ from dotenv import load_dotenv
33
+
34
+ from nat.utils.log_levels import LOG_LEVELS
35
+
36
+ from .commands.configure.configure import configure_command
37
+ from .commands.evaluate import eval_command
38
+ from .commands.info.info import info_command
39
+ from .commands.mcp.mcp import mcp_command
40
+ from .commands.object_store.object_store import object_store_command
41
+ from .commands.optimize import optimizer_command
42
+ from .commands.registry.registry import registry_command
43
+ from .commands.sizing.sizing import sizing
44
+ from .commands.start import start_command
45
+ from .commands.uninstall import uninstall_command
46
+ from .commands.validate import validate_command
47
+ from .commands.workflow.workflow import workflow_command
48
+
49
+ # Load environment variables from .env file, if it exists
50
+ load_dotenv()
51
+
52
+ # Apply at the beginning of the file to avoid issues with asyncio
53
+ nest_asyncio.apply()
54
+
55
+
56
+ def setup_logging(log_level: str):
57
+ """Configure logging with the specified level"""
58
+ numeric_level = LOG_LEVELS.get(log_level.upper(), logging.INFO)
59
+ logging.basicConfig(
60
+ level=numeric_level,
61
+ format="%(asctime)s - %(levelname)-8s - %(name)s:%(lineno)d - %(message)s",
62
+ datefmt="%Y-%m-%d %H:%M:%S",
63
+ )
64
+ return numeric_level
65
+
66
+
67
+ def get_version():
68
+ from importlib.metadata import PackageNotFoundError
69
+ from importlib.metadata import version
70
+ try:
71
+ # Use the distro name to get the version
72
+ return version("nvidia-nat")
73
+ except PackageNotFoundError:
74
+ return "unknown"
75
+
76
+
77
+ @click.group(name="nat", chain=False, invoke_without_command=True, no_args_is_help=True)
78
+ @click.version_option(version=get_version())
79
+ @click.option('--log-level',
80
+ type=click.Choice(LOG_LEVELS.keys(), case_sensitive=False),
81
+ default='INFO',
82
+ help='Set the logging level')
83
+ @click.pass_context
84
+ def cli(ctx: click.Context, log_level: str):
85
+ """Main entrypoint for the NAT CLI"""
86
+
87
+ ctx_dict = ctx.ensure_object(dict)
88
+
89
+ # Setup logging
90
+ numeric_level = setup_logging(log_level)
91
+
92
+ nat_logger = logging.getLogger("nat")
93
+ nat_logger.setLevel(numeric_level)
94
+
95
+ logger = logging.getLogger(__package__)
96
+
97
+ # Set the parent logger for all of the llm examples to use morpheus so we can take advantage of configure_logging
98
+ logger.parent = nat_logger
99
+ logger.setLevel(numeric_level)
100
+
101
+ ctx_dict["start_time"] = time.time()
102
+ ctx_dict["log_level"] = log_level
103
+
104
+
105
+ cli.add_command(configure_command, name="configure")
106
+ cli.add_command(eval_command, name="eval")
107
+ cli.add_command(info_command, name="info")
108
+ cli.add_command(registry_command, name="registry")
109
+ cli.add_command(start_command, name="start")
110
+ cli.add_command(uninstall_command, name="uninstall")
111
+ cli.add_command(validate_command, name="validate")
112
+ cli.add_command(workflow_command, name="workflow")
113
+ cli.add_command(sizing, name="sizing")
114
+ cli.add_command(optimizer_command, name="optimize")
115
+ cli.add_command(object_store_command, name="object-store")
116
+ cli.add_command(mcp_command, name="mcp")
117
+
118
+ # Aliases
119
+ cli.add_command(start_command.get_command(None, "console"), name="run") # type: ignore
120
+ cli.add_command(start_command.get_command(None, "fastapi"), name="serve") # type: ignore
121
+
122
+
123
+ @cli.result_callback()
124
+ @click.pass_context
125
+ def after_pipeline(ctx: click.Context, pipeline_start_time: float, *_, **__):
126
+ logger = logging.getLogger(__name__)
127
+
128
+ end_time = time.time()
129
+
130
+ ctx_dict = ctx.ensure_object(dict)
131
+
132
+ start_time = ctx_dict["start_time"]
133
+
134
+ # Reset the terminal colors, not using print to avoid an additional newline
135
+ for stream in (sys.stdout, sys.stderr):
136
+ stream.write("\x1b[0m")
137
+
138
+ logger.debug("Total time: %.2f sec", end_time - start_time)
139
+
140
+ if (pipeline_start_time is not None):
141
+ logger.debug("Pipeline runtime: %.2f sec", end_time - pipeline_start_time)
nat/cli/main.py ADDED
@@ -0,0 +1,60 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
17
+ # SPDX-License-Identifier: LicenseRef-NvidiaProprietary
18
+ #
19
+ # NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
20
+ # property and proprietary rights in and to this material, related
21
+ # documentation and any modifications thereto. Any use, reproduction,
22
+ # disclosure or distribution of this material and related documentation
23
+ # without an express license agreement from NVIDIA CORPORATION or
24
+ # its affiliates is strictly prohibited.
25
+
26
+
27
+ # The purpose of this function is to allow loading the current directory as a module. This allows relative imports and
28
+ # more specifically `..common` to function correctly
29
+ def run_cli():
30
+ import os
31
+ import sys
32
+
33
+ # Suppress warnings from transformers
34
+ os.environ["TRANSFORMERS_VERBOSITY"] = "error"
35
+
36
+ parent_dir = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
37
+
38
+ if (parent_dir not in sys.path):
39
+ sys.path.append(parent_dir)
40
+
41
+ from nat.cli.entrypoint import cli
42
+
43
+ cli(obj={}, auto_envvar_prefix='NAT', show_default=True, prog_name="nat")
44
+
45
+
46
+ def run_cli_aiq_compat():
47
+ "Entrypoint for the `aiq` compatibility command"
48
+ import warnings
49
+
50
+ # Warn with a UserWarning since DeprecationWarnings are not shown by default
51
+ warnings.warn(
52
+ "The 'aiq' command is deprecated and will be removed in a future release. "
53
+ "Please use the 'nat' command instead.",
54
+ UserWarning,
55
+ stacklevel=2)
56
+ run_cli()
57
+
58
+
59
+ if __name__ == '__main__':
60
+ run_cli()