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,431 @@
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 importlib
17
+ import json
18
+ import math
19
+ from pathlib import Path
20
+
21
+ import pandas as pd
22
+
23
+ from nat.data_models.dataset_handler import EvalDatasetConfig
24
+ from nat.data_models.dataset_handler import EvalDatasetCustomConfig
25
+ from nat.data_models.dataset_handler import EvalDatasetJsonConfig
26
+ from nat.data_models.intermediate_step import IntermediateStep
27
+ from nat.data_models.intermediate_step import IntermediateStepType
28
+ from nat.eval.dataset_handler.dataset_downloader import DatasetDownloader
29
+ from nat.eval.dataset_handler.dataset_filter import DatasetFilter
30
+ from nat.eval.evaluator.evaluator_model import EvalInput
31
+ from nat.eval.evaluator.evaluator_model import EvalInputItem
32
+
33
+
34
+ class DatasetHandler:
35
+ """
36
+ Read the datasets and pre-process (apply filters, deduplicate etc.) before turning them into EvalInput objects.
37
+ One DatasetHandler object is needed for each dataset to be evaluated.
38
+ """
39
+
40
+ def __init__(self,
41
+ dataset_config: EvalDatasetConfig,
42
+ reps: int,
43
+ concurrency: int,
44
+ num_passes: int = 1,
45
+ adjust_dataset_size: bool = False,
46
+ custom_pre_eval_process_function: str | None = None):
47
+ from nat.eval.intermediate_step_adapter import IntermediateStepAdapter
48
+
49
+ self.dataset_config = dataset_config
50
+ self.dataset_filter = DatasetFilter(dataset_config.filter)
51
+ self.reps = reps
52
+
53
+ # number of passes at specific concurrency
54
+ self.concurrency = concurrency
55
+ self.num_passes = num_passes
56
+ self.adjust_dataset_size = adjust_dataset_size
57
+
58
+ # Custom pre-evaluation process function
59
+ self.custom_pre_eval_process_function = custom_pre_eval_process_function
60
+
61
+ # Helpers
62
+ self.intermediate_step_adapter = IntermediateStepAdapter()
63
+
64
+ def is_structured_input(self) -> bool:
65
+ '''Check if the input is structured or unstructured'''
66
+ return not self.dataset_config.structure.disable
67
+
68
+ @property
69
+ def id_key(self) -> str:
70
+ return self.dataset_config.id_key
71
+
72
+ @property
73
+ def question_key(self) -> str:
74
+ return self.dataset_config.structure.question_key
75
+
76
+ @property
77
+ def answer_key(self) -> str:
78
+ return self.dataset_config.structure.answer_key
79
+
80
+ @property
81
+ def generated_answer_key(self) -> str:
82
+ return self.dataset_config.structure.generated_answer_key
83
+
84
+ @property
85
+ def trajectory_key(self) -> str:
86
+ return self.dataset_config.structure.trajectory_key
87
+
88
+ @property
89
+ def expected_trajectory_key(self) -> str:
90
+ return self.dataset_config.structure.expected_trajectory_key
91
+
92
+ def get_eval_input_from_df(self, input_df: pd.DataFrame) -> EvalInput:
93
+
94
+ def create_eval_item(row: pd.Series, structured: bool) -> EvalInputItem:
95
+ """Helper function to create EvalInputItem."""
96
+ return EvalInputItem(
97
+ id=row.get(self.id_key, ""),
98
+ input_obj=row.to_json() if not structured else row.get(self.question_key, ""),
99
+ expected_output_obj=row.get(self.answer_key, "") if structured else "",
100
+ output_obj=row.get(self.generated_answer_key, "") if structured else "",
101
+ trajectory=row.get(self.trajectory_key, []) if structured else [],
102
+ expected_trajectory=row.get(self.expected_trajectory_key, []) if structured else [],
103
+ full_dataset_entry=row.to_dict(),
104
+ )
105
+
106
+ # if input dataframe is empty return an empty list
107
+ if input_df.empty:
108
+ return EvalInput(eval_input_items=[])
109
+
110
+ structured = self.is_structured_input()
111
+ if structured:
112
+ # For structured input, question is mandatory. Ignore rows with missing or empty questions
113
+ input_df = input_df[input_df[self.question_key].notnull() & input_df[self.question_key].str.strip().ne("")]
114
+ eval_input_items = [create_eval_item(row, structured) for _, row in input_df.iterrows()]
115
+
116
+ return EvalInput(eval_input_items=eval_input_items)
117
+
118
+ def setup_reps(self, input_df: pd.DataFrame) -> pd.DataFrame:
119
+ """replicate the rows and update the id to id_key + "_rep" + rep_number"""
120
+ # Replicate the rows
121
+ input_df = pd.concat([input_df] * self.reps, ignore_index=True)
122
+ # Compute repetition index
123
+ rep_index = input_df.groupby(self.dataset_config.id_key).cumcount().astype(str)
124
+ # Convert id_key to string (id can be integer) if needed and update IDs
125
+ input_df[self.dataset_config.id_key] = input_df[self.dataset_config.id_key].astype(str) + "_rep" + rep_index
126
+ # Ensure unique ID values after modification
127
+ input_df.drop_duplicates(subset=[self.dataset_config.id_key], inplace=True)
128
+
129
+ return input_df
130
+
131
+ def adjust_dataset(self, input_df: pd.DataFrame) -> pd.DataFrame:
132
+ """
133
+ Adjust the dataset so its length is a multiple of concurrency.
134
+
135
+ If num_passes > 0:
136
+ dataset size is adjusted to concurrency * num_passes
137
+ else:
138
+ dataset size is adjusted to the largest multiple of concurrency
139
+ that is less than or equal to the current dataset size
140
+ """
141
+ if self.concurrency <= 0:
142
+ raise ValueError("Concurrency must be > 0")
143
+
144
+ if self.num_passes < 0:
145
+ raise ValueError("num_passes must be >= 0")
146
+
147
+ original_size = input_df.shape[0]
148
+
149
+ # Calculate target size
150
+ if self.num_passes > 0:
151
+ # When num_passes is specified, always use concurrency * num_passes
152
+ # This respects the user's intent for exact number of passes
153
+ target_size = self.concurrency * self.num_passes
154
+ # When num_passes = 0, use the largest multiple of concurrency <= original_size
155
+ # If original_size < concurrency, we need at least concurrency rows
156
+ elif original_size >= self.concurrency:
157
+ target_size = (original_size // self.concurrency) * self.concurrency
158
+ else:
159
+ target_size = self.concurrency
160
+
161
+ if target_size == 0:
162
+ raise ValueError("Input dataset too small for even one batch at given concurrency.")
163
+
164
+ id_col = self.dataset_config.id_key
165
+
166
+ # If we need more rows than we have, replicate the dataset
167
+ if original_size < target_size:
168
+ # Clean existing _rep suffix if present
169
+ input_df[id_col] = input_df[id_col].astype(str).str.replace(r"_rep\d+$", "", regex=True)
170
+
171
+ # Calculate how many complete copies we need
172
+ copies_needed = math.ceil(target_size / original_size)
173
+
174
+ # Create the replicated dataframe
175
+ replicated_dfs = []
176
+ for i in range(copies_needed):
177
+ df_copy = input_df.copy()
178
+ if i > 0: # Add suffix to all but the first copy
179
+ df_copy[id_col] = df_copy[id_col].astype(str) + f"_rep{i}"
180
+ replicated_dfs.append(df_copy)
181
+
182
+ input_df = pd.concat(replicated_dfs, ignore_index=True)
183
+
184
+ # Return exactly the target size
185
+ return input_df.head(target_size)
186
+
187
+ def get_eval_input_from_dataset(self, dataset: str) -> EvalInput:
188
+ # read the dataset and convert it to EvalInput
189
+
190
+ # if a dataset file has been provided in the command line, use that
191
+ dataset_config = EvalDatasetJsonConfig(file_path=dataset) if dataset else self.dataset_config
192
+
193
+ # Handle custom dataset type with special processing
194
+ if isinstance(self.dataset_config, EvalDatasetCustomConfig):
195
+ return self._handle_custom_dataset(dataset)
196
+
197
+ # Download the dataset if it is remote
198
+ downloader = DatasetDownloader(dataset_config=dataset_config)
199
+ downloader.download_dataset()
200
+
201
+ parser, kwargs = dataset_config.parser()
202
+ # Parse the dataset into a DataFrame
203
+ input_df = parser(dataset_config.file_path, **kwargs)
204
+
205
+ # Apply standard preprocessing and convert to EvalInput
206
+ return self._preprocess_eval_dataframe(input_df)
207
+
208
+ def _preprocess_dataframe(self, input_df: pd.DataFrame) -> pd.DataFrame:
209
+ """
210
+ Apply standard preprocessing to a DataFrame: filters, deduplication, repetitions, and size adjustment.
211
+
212
+ Args:
213
+ input_df: DataFrame to preprocess
214
+
215
+ Returns:
216
+ Preprocessed DataFrame
217
+ """
218
+ # Apply filters and deduplicate
219
+ input_df = self.dataset_filter.apply_filters(input_df)
220
+ input_df.drop_duplicates(subset=[self.dataset_config.id_key], inplace=True)
221
+
222
+ if self.reps > 1 and self.adjust_dataset_size:
223
+ raise ValueError("reps and adjust_dataset_size are mutually exclusive")
224
+
225
+ # If more than one repetition is needed, replicate the rows
226
+ if self.reps > 1:
227
+ input_df = self.setup_reps(input_df)
228
+ elif self.adjust_dataset_size:
229
+ input_df = self.adjust_dataset(input_df)
230
+
231
+ return input_df
232
+
233
+ def _preprocess_eval_dataframe(self, input_df: pd.DataFrame) -> EvalInput:
234
+ """
235
+ Apply standard preprocessing to a DataFrame and convert to EvalInput.
236
+
237
+ Args:
238
+ input_df: DataFrame to preprocess
239
+
240
+ Returns:
241
+ Preprocessed EvalInput object
242
+ """
243
+ processed_df = self._preprocess_dataframe(input_df)
244
+ return self.get_eval_input_from_df(processed_df)
245
+
246
+ def _preprocess_eval_input(self, eval_input: EvalInput) -> EvalInput:
247
+ """
248
+ Apply standard preprocessing to an EvalInput object.
249
+
250
+ Thin wrapper that converts EvalInput to DataFrame, processes it, and converts back.
251
+
252
+ Args:
253
+ eval_input: EvalInput object to preprocess
254
+
255
+ Returns:
256
+ Preprocessed EvalInput object
257
+ """
258
+ if not eval_input.eval_input_items:
259
+ return eval_input
260
+
261
+ input_df = self._eval_input_to_dataframe(eval_input)
262
+ return self._preprocess_eval_dataframe(input_df)
263
+
264
+ def _handle_custom_dataset(self, dataset: str | None) -> EvalInput:
265
+ """
266
+ Handle custom dataset type by calling the user-defined function
267
+ and applying standard preprocessing to the result.
268
+
269
+ Args:
270
+ dataset: Optional dataset file path from command line
271
+
272
+ Returns:
273
+ Preprocessed EvalInput object
274
+ """
275
+ # Determine input path - use command line dataset or config file_path
276
+ input_path = Path(dataset) if dataset else Path(self.dataset_config.file_path)
277
+
278
+ # Download the dataset if it is remote (for custom datasets too)
279
+ downloader = DatasetDownloader(dataset_config=self.dataset_config)
280
+ downloader.download_dataset()
281
+
282
+ # Load and call custom function
283
+ custom_function, kwargs = self.dataset_config.parser()
284
+
285
+ try:
286
+ # Call the custom function with file_path and kwargs
287
+ eval_input = custom_function(file_path=input_path, **kwargs)
288
+
289
+ if not isinstance(eval_input, EvalInput):
290
+ raise ValueError(f"Custom function must return an EvalInput object, "
291
+ f"but returned {type(eval_input)}")
292
+
293
+ except Exception as e:
294
+ raise RuntimeError(f"Error calling custom dataset function: {e}") from e
295
+
296
+ # Apply standard preprocessing (filters, deduplication, repetitions)
297
+ return self._preprocess_eval_input(eval_input)
298
+
299
+ def _eval_input_to_dataframe(self, eval_input: EvalInput) -> pd.DataFrame:
300
+ """
301
+ Convert an EvalInput object to a pandas DataFrame for processing.
302
+
303
+ Args:
304
+ eval_input: EvalInput object to convert
305
+
306
+ Returns:
307
+ DataFrame representation of the EvalInput
308
+ """
309
+ data = []
310
+ for item in eval_input.eval_input_items:
311
+ row = item.full_dataset_entry.copy() if item.full_dataset_entry else {}
312
+
313
+ # Ensure key fields are present
314
+ row[self.id_key] = item.id
315
+ if self.is_structured_input():
316
+ row[self.question_key] = item.input_obj
317
+ row[self.answer_key] = item.expected_output_obj
318
+ row[self.generated_answer_key] = item.output_obj
319
+ row[self.trajectory_key] = item.trajectory
320
+ row[self.expected_trajectory_key] = item.expected_trajectory
321
+
322
+ data.append(row)
323
+
324
+ return pd.DataFrame(data)
325
+
326
+ def filter_intermediate_steps(self,
327
+ intermediate_steps: list[IntermediateStep],
328
+ event_filter: list[IntermediateStepType] | None = None) -> list[dict]:
329
+ """
330
+ Filter out the intermediate steps that are not relevant for evaluation.
331
+ The output is written with with the intention of re-running the evaluation using the original config file.
332
+ """
333
+ if event_filter is None:
334
+ event_filter = self.intermediate_step_adapter.DEFAULT_EVENT_FILTER
335
+ filtered_steps = self.intermediate_step_adapter.filter_intermediate_steps(intermediate_steps, event_filter)
336
+ return self.intermediate_step_adapter.serialize_intermediate_steps(filtered_steps)
337
+
338
+ def pre_eval_process_eval_input(self, eval_input: EvalInput) -> EvalInput:
339
+ """
340
+ Pre-evaluation process the eval input using custom function if provided.
341
+
342
+ The custom pre-evaluation process function should have the signature:
343
+ def custom_pre_eval_process(item: EvalInputItem) -> EvalInputItem
344
+
345
+ The framework will iterate through all items and call this function on each one.
346
+
347
+ Args:
348
+ eval_input: The EvalInput object to pre-evaluation process
349
+
350
+ Returns:
351
+ The pre-evaluation processed EvalInput object
352
+ """
353
+ if self.custom_pre_eval_process_function:
354
+ try:
355
+ custom_function = self._load_custom_pre_eval_process_function()
356
+ processed_items = []
357
+
358
+ for item in eval_input.eval_input_items:
359
+ processed_item = custom_function(item)
360
+ if not isinstance(processed_item, EvalInputItem):
361
+ raise TypeError(f"Custom pre-evaluation '{self.custom_pre_eval_process_function}' must return "
362
+ f"EvalInputItem, got {type(processed_item)}")
363
+ processed_items.append(processed_item)
364
+
365
+ return EvalInput(eval_input_items=processed_items)
366
+ except Exception as e:
367
+ raise RuntimeError(f"Error calling custom pre-evaluation process function "
368
+ f"'{self.custom_pre_eval_process_function}': {e}") from e
369
+
370
+ return eval_input
371
+
372
+ def _load_custom_pre_eval_process_function(self):
373
+ """
374
+ Import and return the custom pre-evaluation process function using standard Python import path.
375
+
376
+ The function should process individual EvalInputItem objects.
377
+ """
378
+ # Split the function path to get module and function name
379
+ if "." not in self.custom_pre_eval_process_function:
380
+ raise ValueError(f"Invalid custom_pre_eval_process_function '{self.custom_pre_eval_process_function}'. "
381
+ "Expected format: '<module_path>.<function_name>'")
382
+ module_path, function_name = self.custom_pre_eval_process_function.rsplit(".", 1)
383
+
384
+ # Import the module
385
+ module = importlib.import_module(module_path)
386
+
387
+ # Get the function from the module
388
+ if not hasattr(module, function_name):
389
+ raise AttributeError(f"Function '{function_name}' not found in module '{module_path}'")
390
+
391
+ custom_function = getattr(module, function_name)
392
+
393
+ if not callable(custom_function):
394
+ raise ValueError(f"'{self.custom_pre_eval_process_function}' is not callable")
395
+
396
+ return custom_function
397
+
398
+ def publish_eval_input(self,
399
+ eval_input,
400
+ workflow_output_step_filter: list[IntermediateStepType] | None = None) -> str:
401
+ """
402
+ Convert the EvalInput object to a JSON output for storing in a file. Use the orginal keys to
403
+ allow re-running evaluation using the orignal config file and '--skip_workflow' option.
404
+ """
405
+
406
+ def parse_if_json_string(value):
407
+ if isinstance(value, str):
408
+ try:
409
+ return json.loads(value)
410
+ except json.JSONDecodeError:
411
+ return value
412
+ if hasattr(value, "model_dump"):
413
+ return value.model_dump()
414
+ return value
415
+
416
+ indent = 2
417
+ if self.is_structured_input():
418
+ # Extract structured data from EvalInputItems
419
+ data = [{
420
+ self.id_key: item.id,
421
+ self.question_key: item.input_obj,
422
+ self.answer_key: item.expected_output_obj,
423
+ self.generated_answer_key: item.output_obj,
424
+ self.trajectory_key: self.filter_intermediate_steps(item.trajectory, workflow_output_step_filter),
425
+ self.expected_trajectory_key: self.filter_intermediate_steps(item.expected_trajectory),
426
+ } for item in eval_input.eval_input_items]
427
+ else:
428
+ # Unstructured case: return only raw output objects as a JSON array
429
+ data = [parse_if_json_string(item.output_obj) for item in eval_input.eval_input_items]
430
+
431
+ return json.dumps(data, indent=indent, ensure_ascii=False, default=str)