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
nat/runtime/runner.py ADDED
@@ -0,0 +1,292 @@
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 typing
18
+ import uuid
19
+ from enum import Enum
20
+
21
+ from nat.builder.context import Context
22
+ from nat.builder.context import ContextState
23
+ from nat.builder.function import Function
24
+ from nat.data_models.intermediate_step import IntermediateStepPayload
25
+ from nat.data_models.intermediate_step import IntermediateStepType
26
+ from nat.data_models.intermediate_step import StreamEventData
27
+ from nat.data_models.intermediate_step import TraceMetadata
28
+ from nat.data_models.invocation_node import InvocationNode
29
+ from nat.observability.exporter_manager import ExporterManager
30
+ from nat.utils.reactive.subject import Subject
31
+
32
+ logger = logging.getLogger(__name__)
33
+
34
+
35
+ class UserManagerBase:
36
+ pass
37
+
38
+
39
+ class RunnerState(Enum):
40
+ UNINITIALIZED = 0
41
+ INITIALIZED = 1
42
+ RUNNING = 2
43
+ COMPLETED = 3
44
+ FAILED = 4
45
+
46
+
47
+ _T = typing.TypeVar("_T")
48
+
49
+
50
+ class Runner:
51
+
52
+ def __init__(self,
53
+ input_message: typing.Any,
54
+ entry_fn: Function,
55
+ context_state: ContextState,
56
+ exporter_manager: ExporterManager):
57
+ """
58
+ The Runner class is used to run a workflow. It handles converting input and output data types and running the
59
+ workflow with the specified concurrency.
60
+
61
+ Parameters
62
+ ----------
63
+ input_message : typing.Any
64
+ The input message to the workflow
65
+ entry_fn : Function
66
+ The entry function to the workflow
67
+ context_state : ContextState
68
+ The context state to use
69
+ exporter_manager : ExporterManager
70
+ The exporter manager to use
71
+ """
72
+
73
+ if (entry_fn is None):
74
+ raise ValueError("entry_fn cannot be None")
75
+
76
+ self._entry_fn = entry_fn
77
+ self._context_state = context_state
78
+ self._context = Context(self._context_state)
79
+
80
+ self._state = RunnerState.UNINITIALIZED
81
+
82
+ self._input_message_token = None
83
+
84
+ # Before we start, we need to convert the input message to the workflow input type
85
+ self._input_message = input_message
86
+
87
+ self._exporter_manager = exporter_manager
88
+
89
+ @property
90
+ def context(self) -> Context:
91
+ return self._context
92
+
93
+ def convert(self, value: typing.Any, to_type: type[_T]) -> _T:
94
+ return self._entry_fn.convert(value, to_type)
95
+
96
+ async def __aenter__(self):
97
+
98
+ # Set the input message on the context
99
+ self._input_message_token = self._context_state.input_message.set(self._input_message)
100
+
101
+ # Create reactive event stream
102
+ self._context_state.event_stream.set(Subject())
103
+ self._context_state.active_function.set(InvocationNode(
104
+ function_name="root",
105
+ function_id="root",
106
+ ))
107
+
108
+ if (self._state == RunnerState.UNINITIALIZED):
109
+ self._state = RunnerState.INITIALIZED
110
+ else:
111
+ raise ValueError("Cannot enter the context more than once")
112
+
113
+ return self
114
+
115
+ async def __aexit__(self, exc_type, exc_value, traceback):
116
+
117
+ if (self._input_message_token is None):
118
+ raise ValueError("Cannot exit the context without entering it")
119
+
120
+ self._context_state.input_message.reset(self._input_message_token)
121
+
122
+ if (self._state not in (RunnerState.COMPLETED, RunnerState.FAILED)):
123
+ raise ValueError("Cannot exit the context without completing the workflow")
124
+
125
+ @typing.overload
126
+ async def result(self) -> typing.Any:
127
+ ...
128
+
129
+ @typing.overload
130
+ async def result(self, to_type: type[_T]) -> _T:
131
+ ...
132
+
133
+ async def result(self, to_type: type | None = None):
134
+
135
+ if (self._state != RunnerState.INITIALIZED):
136
+ raise ValueError("Cannot run the workflow without entering the context")
137
+
138
+ token_run_id = None
139
+ token_trace_id = None
140
+ try:
141
+ self._state = RunnerState.RUNNING
142
+
143
+ if (not self._entry_fn.has_single_output):
144
+ raise ValueError("Workflow does not support single output")
145
+
146
+ # Establish workflow run and trace identifiers
147
+ existing_run_id = self._context_state.workflow_run_id.get()
148
+ existing_trace_id = self._context_state.workflow_trace_id.get()
149
+
150
+ workflow_run_id = existing_run_id or str(uuid.uuid4())
151
+
152
+ workflow_trace_id = existing_trace_id or uuid.uuid4().int
153
+
154
+ token_run_id = self._context_state.workflow_run_id.set(workflow_run_id)
155
+ token_trace_id = self._context_state.workflow_trace_id.set(workflow_trace_id)
156
+
157
+ # Prepare workflow-level intermediate step identifiers
158
+ workflow_step_uuid = str(uuid.uuid4())
159
+ workflow_name = getattr(self._entry_fn, 'instance_name', None) or "workflow"
160
+
161
+ async with self._exporter_manager.start(context_state=self._context_state):
162
+ # Emit WORKFLOW_START
163
+ start_metadata = TraceMetadata(
164
+ provided_metadata={
165
+ "workflow_run_id": workflow_run_id,
166
+ "workflow_trace_id": f"{workflow_trace_id:032x}",
167
+ "conversation_id": self._context_state.conversation_id.get(),
168
+ })
169
+ self._context.intermediate_step_manager.push_intermediate_step(
170
+ IntermediateStepPayload(UUID=workflow_step_uuid,
171
+ event_type=IntermediateStepType.WORKFLOW_START,
172
+ name=workflow_name,
173
+ metadata=start_metadata))
174
+
175
+ result = await self._entry_fn.ainvoke(self._input_message, to_type=to_type) # type: ignore
176
+
177
+ # Emit WORKFLOW_END with output
178
+ end_metadata = TraceMetadata(
179
+ provided_metadata={
180
+ "workflow_run_id": workflow_run_id,
181
+ "workflow_trace_id": f"{workflow_trace_id:032x}",
182
+ "conversation_id": self._context_state.conversation_id.get(),
183
+ })
184
+ self._context.intermediate_step_manager.push_intermediate_step(
185
+ IntermediateStepPayload(UUID=workflow_step_uuid,
186
+ event_type=IntermediateStepType.WORKFLOW_END,
187
+ name=workflow_name,
188
+ metadata=end_metadata,
189
+ data=StreamEventData(output=result)))
190
+
191
+ event_stream = self._context_state.event_stream.get()
192
+ if event_stream:
193
+ event_stream.on_complete()
194
+
195
+ self._state = RunnerState.COMPLETED
196
+
197
+ return result
198
+ except Exception as e:
199
+ logger.error("Error running workflow: %s", e)
200
+ event_stream = self._context_state.event_stream.get()
201
+ if event_stream:
202
+ event_stream.on_complete()
203
+ self._state = RunnerState.FAILED
204
+ raise
205
+ finally:
206
+ if token_run_id is not None:
207
+ self._context_state.workflow_run_id.reset(token_run_id)
208
+ if token_trace_id is not None:
209
+ self._context_state.workflow_trace_id.reset(token_trace_id)
210
+
211
+ async def result_stream(self, to_type: type | None = None):
212
+
213
+ if (self._state != RunnerState.INITIALIZED):
214
+ raise ValueError("Cannot run the workflow without entering the context")
215
+
216
+ token_run_id = None
217
+ token_trace_id = None
218
+ try:
219
+ self._state = RunnerState.RUNNING
220
+
221
+ if (not self._entry_fn.has_streaming_output):
222
+ raise ValueError("Workflow does not support streaming output")
223
+
224
+ # Establish workflow run and trace identifiers
225
+ existing_run_id = self._context_state.workflow_run_id.get()
226
+ existing_trace_id = self._context_state.workflow_trace_id.get()
227
+
228
+ workflow_run_id = existing_run_id or str(uuid.uuid4())
229
+
230
+ workflow_trace_id = existing_trace_id or uuid.uuid4().int
231
+
232
+ token_run_id = self._context_state.workflow_run_id.set(workflow_run_id)
233
+ token_trace_id = self._context_state.workflow_trace_id.set(workflow_trace_id)
234
+
235
+ # Prepare workflow-level intermediate step identifiers
236
+ workflow_step_uuid = str(uuid.uuid4())
237
+ workflow_name = getattr(self._entry_fn, 'instance_name', None) or "workflow"
238
+
239
+ # Run the workflow
240
+ async with self._exporter_manager.start(context_state=self._context_state):
241
+ # Emit WORKFLOW_START
242
+ start_metadata = TraceMetadata(
243
+ provided_metadata={
244
+ "workflow_run_id": workflow_run_id,
245
+ "workflow_trace_id": f"{workflow_trace_id:032x}",
246
+ "conversation_id": self._context_state.conversation_id.get(),
247
+ })
248
+ self._context.intermediate_step_manager.push_intermediate_step(
249
+ IntermediateStepPayload(UUID=workflow_step_uuid,
250
+ event_type=IntermediateStepType.WORKFLOW_START,
251
+ name=workflow_name,
252
+ metadata=start_metadata))
253
+
254
+ async for m in self._entry_fn.astream(self._input_message, to_type=to_type): # type: ignore
255
+ yield m
256
+
257
+ # Emit WORKFLOW_END
258
+ end_metadata = TraceMetadata(
259
+ provided_metadata={
260
+ "workflow_run_id": workflow_run_id,
261
+ "workflow_trace_id": f"{workflow_trace_id:032x}",
262
+ "conversation_id": self._context_state.conversation_id.get(),
263
+ })
264
+ self._context.intermediate_step_manager.push_intermediate_step(
265
+ IntermediateStepPayload(UUID=workflow_step_uuid,
266
+ event_type=IntermediateStepType.WORKFLOW_END,
267
+ name=workflow_name,
268
+ metadata=end_metadata))
269
+ self._state = RunnerState.COMPLETED
270
+
271
+ # Close the intermediate stream
272
+ event_stream = self._context_state.event_stream.get()
273
+ if event_stream:
274
+ event_stream.on_complete()
275
+
276
+ except Exception as e:
277
+ logger.error("Error running workflow: %s", e)
278
+ event_stream = self._context_state.event_stream.get()
279
+ if event_stream:
280
+ event_stream.on_complete()
281
+ self._state = RunnerState.FAILED
282
+ raise
283
+ finally:
284
+ if token_run_id is not None:
285
+ self._context_state.workflow_run_id.reset(token_run_id)
286
+ if token_trace_id is not None:
287
+ self._context_state.workflow_trace_id.reset(token_trace_id)
288
+
289
+
290
+ # Compatibility aliases with previous releases
291
+ AIQRunnerState = RunnerState
292
+ AIQRunner = Runner
nat/runtime/session.py ADDED
@@ -0,0 +1,223 @@
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 asyncio
17
+ import contextvars
18
+ import typing
19
+ import uuid
20
+ from collections.abc import Awaitable
21
+ from collections.abc import Callable
22
+ from contextlib import asynccontextmanager
23
+ from contextlib import nullcontext
24
+
25
+ from fastapi import WebSocket
26
+ from starlette.requests import HTTPConnection
27
+ from starlette.requests import Request
28
+
29
+ from nat.builder.context import Context
30
+ from nat.builder.context import ContextState
31
+ from nat.builder.workflow import Workflow
32
+ from nat.data_models.authentication import AuthenticatedContext
33
+ from nat.data_models.authentication import AuthFlowType
34
+ from nat.data_models.authentication import AuthProviderBaseConfig
35
+ from nat.data_models.config import Config
36
+ from nat.data_models.interactive import HumanResponse
37
+ from nat.data_models.interactive import InteractionPrompt
38
+
39
+ _T = typing.TypeVar("_T")
40
+
41
+
42
+ class UserManagerBase:
43
+ pass
44
+
45
+
46
+ class SessionManager:
47
+
48
+ def __init__(self, workflow: Workflow, max_concurrency: int = 8):
49
+ """
50
+ The SessionManager class is used to run and manage a user workflow session. It runs and manages the context,
51
+ and configuration of a workflow with the specified concurrency.
52
+
53
+ Parameters
54
+ ----------
55
+ workflow : Workflow
56
+ The workflow to run
57
+ max_concurrency : int, optional
58
+ The maximum number of simultaneous workflow invocations, by default 8
59
+ """
60
+
61
+ if (workflow is None):
62
+ raise ValueError("Workflow cannot be None")
63
+
64
+ self._workflow: Workflow = workflow
65
+
66
+ self._max_concurrency = max_concurrency
67
+ self._context_state = ContextState.get()
68
+ self._context = Context(self._context_state)
69
+
70
+ # We save the context because Uvicorn spawns a new process
71
+ # for each request, and we need to restore the context vars
72
+ self._saved_context = contextvars.copy_context()
73
+
74
+ if (max_concurrency > 0):
75
+ self._semaphore = asyncio.Semaphore(max_concurrency)
76
+ else:
77
+ # If max_concurrency is 0, then we don't need to limit the concurrency but we still need a context
78
+ self._semaphore = nullcontext()
79
+
80
+ @property
81
+ def config(self) -> Config:
82
+ return self._workflow.config
83
+
84
+ @property
85
+ def workflow(self) -> Workflow:
86
+ return self._workflow
87
+
88
+ @property
89
+ def context(self) -> Context:
90
+ return self._context
91
+
92
+ @asynccontextmanager
93
+ async def session(self,
94
+ user_manager=None,
95
+ http_connection: HTTPConnection | None = None,
96
+ user_message_id: str | None = None,
97
+ conversation_id: str | None = None,
98
+ user_input_callback: Callable[[InteractionPrompt], Awaitable[HumanResponse]] = None,
99
+ user_authentication_callback: Callable[[AuthProviderBaseConfig, AuthFlowType],
100
+ Awaitable[AuthenticatedContext | None]] = None):
101
+
102
+ token_user_input = None
103
+ if user_input_callback is not None:
104
+ token_user_input = self._context_state.user_input_callback.set(user_input_callback)
105
+
106
+ token_user_manager = None
107
+ if user_manager is not None:
108
+ token_user_manager = self._context_state.user_manager.set(user_manager)
109
+
110
+ token_user_authentication = None
111
+ if user_authentication_callback is not None:
112
+ token_user_authentication = self._context_state.user_auth_callback.set(user_authentication_callback)
113
+
114
+ if isinstance(http_connection, WebSocket):
115
+ self.set_metadata_from_websocket(http_connection, user_message_id, conversation_id)
116
+
117
+ if isinstance(http_connection, Request):
118
+ self.set_metadata_from_http_request(http_connection)
119
+
120
+ try:
121
+ yield self
122
+ finally:
123
+ if token_user_manager is not None:
124
+ self._context_state.user_manager.reset(token_user_manager)
125
+ if token_user_input is not None:
126
+ self._context_state.user_input_callback.reset(token_user_input)
127
+ if token_user_authentication is not None:
128
+ self._context_state.user_auth_callback.reset(token_user_authentication)
129
+
130
+ @asynccontextmanager
131
+ async def run(self, message):
132
+ """
133
+ Start a workflow run
134
+ """
135
+ async with self._semaphore:
136
+ # Apply the saved context
137
+ for k, v in self._saved_context.items():
138
+ k.set(v)
139
+
140
+ async with self._workflow.run(message) as runner:
141
+ yield runner
142
+
143
+ def set_metadata_from_http_request(self, request: Request) -> None:
144
+ """
145
+ Extracts and sets user metadata request attributes from a HTTP request.
146
+ If request is None, no attributes are set.
147
+ """
148
+ self._context.metadata._request.method = getattr(request, "method", None)
149
+ self._context.metadata._request.url_path = request.url.path
150
+ self._context.metadata._request.url_port = request.url.port
151
+ self._context.metadata._request.url_scheme = request.url.scheme
152
+ self._context.metadata._request.headers = request.headers
153
+ self._context.metadata._request.query_params = request.query_params
154
+ self._context.metadata._request.path_params = request.path_params
155
+ self._context.metadata._request.client_host = request.client.host
156
+ self._context.metadata._request.client_port = request.client.port
157
+ self._context.metadata._request.cookies = request.cookies
158
+
159
+ if request.headers.get("conversation-id"):
160
+ self._context_state.conversation_id.set(request.headers["conversation-id"])
161
+
162
+ if request.headers.get("user-message-id"):
163
+ self._context_state.user_message_id.set(request.headers["user-message-id"])
164
+
165
+ # W3C Trace Context header: traceparent: 00-<trace-id>-<span-id>-<flags>
166
+ traceparent = request.headers.get("traceparent")
167
+ if traceparent:
168
+ try:
169
+ parts = traceparent.split("-")
170
+ if len(parts) >= 4:
171
+ trace_id_hex = parts[1]
172
+ if len(trace_id_hex) == 32:
173
+ trace_id_int = uuid.UUID(trace_id_hex).int
174
+ self._context_state.workflow_trace_id.set(trace_id_int)
175
+ except Exception:
176
+ pass
177
+
178
+ if not self._context_state.workflow_trace_id.get():
179
+ workflow_trace_id = request.headers.get("workflow-trace-id")
180
+ if workflow_trace_id:
181
+ try:
182
+ self._context_state.workflow_trace_id.set(uuid.UUID(workflow_trace_id).int)
183
+ except Exception:
184
+ pass
185
+
186
+ workflow_run_id = request.headers.get("workflow-run-id")
187
+ if workflow_run_id:
188
+ self._context_state.workflow_run_id.set(workflow_run_id)
189
+
190
+ def set_metadata_from_websocket(self,
191
+ websocket: WebSocket,
192
+ user_message_id: str | None,
193
+ conversation_id: str | None) -> None:
194
+ """
195
+ Extracts and sets user metadata for WebSocket connections.
196
+ """
197
+
198
+ # Extract cookies from WebSocket headers (similar to HTTP request)
199
+ if websocket and hasattr(websocket, 'scope') and 'headers' in websocket.scope:
200
+ cookies = {}
201
+ for header_name, header_value in websocket.scope.get('headers', []):
202
+ if header_name == b'cookie':
203
+ cookie_header = header_value.decode('utf-8')
204
+ # Parse cookie header: "name1=value1; name2=value2"
205
+ for cookie in cookie_header.split(';'):
206
+ cookie = cookie.strip()
207
+ if '=' in cookie:
208
+ name, value = cookie.split('=', 1)
209
+ cookies[name.strip()] = value.strip()
210
+
211
+ # Set cookies in metadata (same as HTTP request)
212
+ self._context.metadata._request.cookies = cookies
213
+ self._context_state.metadata.set(self._context.metadata)
214
+
215
+ if conversation_id is not None:
216
+ self._context_state.conversation_id.set(conversation_id)
217
+
218
+ if user_message_id is not None:
219
+ self._context_state.user_message_id.set(user_message_id)
220
+
221
+
222
+ # Compatibility aliases with previous releases
223
+ AIQSessionManager = SessionManager
@@ -0,0 +1,130 @@
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
+ from starlette.datastructures import Headers
17
+ from starlette.datastructures import QueryParams
18
+
19
+ from nat.data_models.api_server import Request
20
+
21
+
22
+ class RequestAttributes:
23
+ """
24
+ The RequestAttributes class is responsible for managing user http and webscoket session
25
+ metadata. It provides a way to store and expose session attributes to workflow tools.
26
+ """
27
+
28
+ def __init__(self) -> None:
29
+ self._request: Request = Request()
30
+
31
+ @property
32
+ def method(self) -> str | None:
33
+ """
34
+ This property retrieves the HTTP method of the request.
35
+ It can be GET, POST, PUT, DELETE, etc.
36
+
37
+ Returns:
38
+ str | None
39
+ """
40
+ return self._request.method
41
+
42
+ @property
43
+ def url_path(self) -> str | None:
44
+ """
45
+ This property retrieves the path from the URL of the request.
46
+
47
+ Returns:
48
+ str | None
49
+ """
50
+ return self._request.url_path
51
+
52
+ @property
53
+ def url_port(self) -> int | None:
54
+ """
55
+ This property retrieves the port number from the URL of the request.
56
+
57
+ Returns:
58
+ int | None
59
+ """
60
+ return self._request.url_port
61
+
62
+ @property
63
+ def url_scheme(self) -> str | None:
64
+ """
65
+ This property retrieves the scheme from the URL of the request.
66
+
67
+ Returns:
68
+ str | None
69
+ """
70
+ return self._request.url_scheme
71
+
72
+ @property
73
+ def headers(self) -> Headers | None:
74
+ """
75
+ This property retrieves the headers from the request stored in a dictionary-like object.
76
+
77
+ Returns:
78
+ Headers | None
79
+ """
80
+ return self._request.headers
81
+
82
+ @property
83
+ def query_params(self) -> QueryParams | None:
84
+ """
85
+ This property retrieves the query parameters from the request stored in a dictionary-like object.
86
+
87
+ Returns:
88
+ QueryParams | None
89
+ """
90
+ return self._request.query_params
91
+
92
+ @property
93
+ def path_params(self) -> dict[str, str] | None:
94
+ """
95
+ This property retrieves the path parameters from the request stored in a dictionary-like object.
96
+
97
+ Returns:
98
+ dict[str, str] | None
99
+ """
100
+ return self._request.path_params
101
+
102
+ @property
103
+ def client_host(self) -> str | None:
104
+ """
105
+ This property retrieves the clients remote hostname or IP address.
106
+
107
+ Returns:
108
+ str | None
109
+ """
110
+ return self._request.client_host
111
+
112
+ @property
113
+ def client_port(self) -> int | None:
114
+ """
115
+ This property retrieves the clients remote port number from which the client is connecting to.
116
+
117
+ Returns:
118
+ int | None
119
+ """
120
+ return self._request.client_port
121
+
122
+ @property
123
+ def cookies(self) -> dict[str, str] | None:
124
+ """
125
+ This property retrieves the cookies from the request stored in a dictionary-like object.
126
+
127
+ Returns:
128
+ dict[str, str] | None
129
+ """
130
+ return self._request.cookies
File without changes