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.
- aiq/__init__.py +66 -0
- nat/agent/__init__.py +0 -0
- nat/agent/base.py +265 -0
- nat/agent/dual_node.py +72 -0
- nat/agent/prompt_optimizer/__init__.py +0 -0
- nat/agent/prompt_optimizer/prompt.py +68 -0
- nat/agent/prompt_optimizer/register.py +149 -0
- nat/agent/react_agent/__init__.py +0 -0
- nat/agent/react_agent/agent.py +394 -0
- nat/agent/react_agent/output_parser.py +104 -0
- nat/agent/react_agent/prompt.py +44 -0
- nat/agent/react_agent/register.py +168 -0
- nat/agent/reasoning_agent/__init__.py +0 -0
- nat/agent/reasoning_agent/reasoning_agent.py +227 -0
- nat/agent/register.py +23 -0
- nat/agent/rewoo_agent/__init__.py +0 -0
- nat/agent/rewoo_agent/agent.py +593 -0
- nat/agent/rewoo_agent/prompt.py +107 -0
- nat/agent/rewoo_agent/register.py +175 -0
- nat/agent/tool_calling_agent/__init__.py +0 -0
- nat/agent/tool_calling_agent/agent.py +246 -0
- nat/agent/tool_calling_agent/register.py +129 -0
- nat/authentication/__init__.py +14 -0
- nat/authentication/api_key/__init__.py +14 -0
- nat/authentication/api_key/api_key_auth_provider.py +96 -0
- nat/authentication/api_key/api_key_auth_provider_config.py +124 -0
- nat/authentication/api_key/register.py +26 -0
- nat/authentication/credential_validator/__init__.py +14 -0
- nat/authentication/credential_validator/bearer_token_validator.py +557 -0
- nat/authentication/exceptions/__init__.py +14 -0
- nat/authentication/exceptions/api_key_exceptions.py +38 -0
- nat/authentication/http_basic_auth/__init__.py +0 -0
- nat/authentication/http_basic_auth/http_basic_auth_provider.py +81 -0
- nat/authentication/http_basic_auth/register.py +30 -0
- nat/authentication/interfaces.py +96 -0
- nat/authentication/oauth2/__init__.py +14 -0
- nat/authentication/oauth2/oauth2_auth_code_flow_provider.py +140 -0
- nat/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +39 -0
- nat/authentication/oauth2/oauth2_resource_server_config.py +124 -0
- nat/authentication/oauth2/register.py +25 -0
- nat/authentication/register.py +20 -0
- nat/builder/__init__.py +0 -0
- nat/builder/builder.py +317 -0
- nat/builder/component_utils.py +320 -0
- nat/builder/context.py +321 -0
- nat/builder/embedder.py +24 -0
- nat/builder/eval_builder.py +166 -0
- nat/builder/evaluator.py +29 -0
- nat/builder/framework_enum.py +25 -0
- nat/builder/front_end.py +73 -0
- nat/builder/function.py +714 -0
- nat/builder/function_base.py +380 -0
- nat/builder/function_info.py +625 -0
- nat/builder/intermediate_step_manager.py +206 -0
- nat/builder/llm.py +25 -0
- nat/builder/retriever.py +25 -0
- nat/builder/user_interaction_manager.py +78 -0
- nat/builder/workflow.py +160 -0
- nat/builder/workflow_builder.py +1365 -0
- nat/cli/__init__.py +14 -0
- nat/cli/cli_utils/__init__.py +0 -0
- nat/cli/cli_utils/config_override.py +231 -0
- nat/cli/cli_utils/validation.py +37 -0
- nat/cli/commands/__init__.py +0 -0
- nat/cli/commands/configure/__init__.py +0 -0
- nat/cli/commands/configure/channel/__init__.py +0 -0
- nat/cli/commands/configure/channel/add.py +28 -0
- nat/cli/commands/configure/channel/channel.py +34 -0
- nat/cli/commands/configure/channel/remove.py +30 -0
- nat/cli/commands/configure/channel/update.py +30 -0
- nat/cli/commands/configure/configure.py +33 -0
- nat/cli/commands/evaluate.py +139 -0
- nat/cli/commands/info/__init__.py +14 -0
- nat/cli/commands/info/info.py +47 -0
- nat/cli/commands/info/list_channels.py +32 -0
- nat/cli/commands/info/list_components.py +128 -0
- nat/cli/commands/mcp/__init__.py +14 -0
- nat/cli/commands/mcp/mcp.py +986 -0
- nat/cli/commands/object_store/__init__.py +14 -0
- nat/cli/commands/object_store/object_store.py +227 -0
- nat/cli/commands/optimize.py +90 -0
- nat/cli/commands/registry/__init__.py +14 -0
- nat/cli/commands/registry/publish.py +88 -0
- nat/cli/commands/registry/pull.py +118 -0
- nat/cli/commands/registry/registry.py +36 -0
- nat/cli/commands/registry/remove.py +108 -0
- nat/cli/commands/registry/search.py +153 -0
- nat/cli/commands/sizing/__init__.py +14 -0
- nat/cli/commands/sizing/calc.py +297 -0
- nat/cli/commands/sizing/sizing.py +27 -0
- nat/cli/commands/start.py +257 -0
- nat/cli/commands/uninstall.py +81 -0
- nat/cli/commands/validate.py +47 -0
- nat/cli/commands/workflow/__init__.py +14 -0
- nat/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- nat/cli/commands/workflow/templates/config.yml.j2 +17 -0
- nat/cli/commands/workflow/templates/pyproject.toml.j2 +25 -0
- nat/cli/commands/workflow/templates/register.py.j2 +4 -0
- nat/cli/commands/workflow/templates/workflow.py.j2 +50 -0
- nat/cli/commands/workflow/workflow.py +37 -0
- nat/cli/commands/workflow/workflow_commands.py +403 -0
- nat/cli/entrypoint.py +141 -0
- nat/cli/main.py +60 -0
- nat/cli/register_workflow.py +522 -0
- nat/cli/type_registry.py +1069 -0
- nat/control_flow/__init__.py +0 -0
- nat/control_flow/register.py +20 -0
- nat/control_flow/router_agent/__init__.py +0 -0
- nat/control_flow/router_agent/agent.py +329 -0
- nat/control_flow/router_agent/prompt.py +48 -0
- nat/control_flow/router_agent/register.py +91 -0
- nat/control_flow/sequential_executor.py +166 -0
- nat/data_models/__init__.py +14 -0
- nat/data_models/agent.py +34 -0
- nat/data_models/api_server.py +843 -0
- nat/data_models/authentication.py +245 -0
- nat/data_models/common.py +171 -0
- nat/data_models/component.py +60 -0
- nat/data_models/component_ref.py +179 -0
- nat/data_models/config.py +434 -0
- nat/data_models/dataset_handler.py +169 -0
- nat/data_models/discovery_metadata.py +305 -0
- nat/data_models/embedder.py +27 -0
- nat/data_models/evaluate.py +130 -0
- nat/data_models/evaluator.py +26 -0
- nat/data_models/front_end.py +26 -0
- nat/data_models/function.py +64 -0
- nat/data_models/function_dependencies.py +80 -0
- nat/data_models/gated_field_mixin.py +242 -0
- nat/data_models/interactive.py +246 -0
- nat/data_models/intermediate_step.py +302 -0
- nat/data_models/invocation_node.py +38 -0
- nat/data_models/llm.py +27 -0
- nat/data_models/logging.py +26 -0
- nat/data_models/memory.py +27 -0
- nat/data_models/object_store.py +44 -0
- nat/data_models/optimizable.py +119 -0
- nat/data_models/optimizer.py +149 -0
- nat/data_models/profiler.py +54 -0
- nat/data_models/registry_handler.py +26 -0
- nat/data_models/retriever.py +30 -0
- nat/data_models/retry_mixin.py +35 -0
- nat/data_models/span.py +228 -0
- nat/data_models/step_adaptor.py +64 -0
- nat/data_models/streaming.py +33 -0
- nat/data_models/swe_bench_model.py +54 -0
- nat/data_models/telemetry_exporter.py +26 -0
- nat/data_models/temperature_mixin.py +44 -0
- nat/data_models/thinking_mixin.py +86 -0
- nat/data_models/top_p_mixin.py +44 -0
- nat/data_models/ttc_strategy.py +30 -0
- nat/embedder/__init__.py +0 -0
- nat/embedder/azure_openai_embedder.py +46 -0
- nat/embedder/nim_embedder.py +59 -0
- nat/embedder/openai_embedder.py +42 -0
- nat/embedder/register.py +22 -0
- nat/eval/__init__.py +14 -0
- nat/eval/config.py +62 -0
- nat/eval/dataset_handler/__init__.py +0 -0
- nat/eval/dataset_handler/dataset_downloader.py +106 -0
- nat/eval/dataset_handler/dataset_filter.py +52 -0
- nat/eval/dataset_handler/dataset_handler.py +431 -0
- nat/eval/evaluate.py +565 -0
- nat/eval/evaluator/__init__.py +14 -0
- nat/eval/evaluator/base_evaluator.py +77 -0
- nat/eval/evaluator/evaluator_model.py +58 -0
- nat/eval/intermediate_step_adapter.py +99 -0
- nat/eval/rag_evaluator/__init__.py +0 -0
- nat/eval/rag_evaluator/evaluate.py +178 -0
- nat/eval/rag_evaluator/register.py +143 -0
- nat/eval/register.py +26 -0
- nat/eval/remote_workflow.py +133 -0
- nat/eval/runners/__init__.py +14 -0
- nat/eval/runners/config.py +39 -0
- nat/eval/runners/multi_eval_runner.py +54 -0
- nat/eval/runtime_evaluator/__init__.py +14 -0
- nat/eval/runtime_evaluator/evaluate.py +123 -0
- nat/eval/runtime_evaluator/register.py +100 -0
- nat/eval/runtime_event_subscriber.py +52 -0
- nat/eval/swe_bench_evaluator/__init__.py +0 -0
- nat/eval/swe_bench_evaluator/evaluate.py +215 -0
- nat/eval/swe_bench_evaluator/register.py +36 -0
- nat/eval/trajectory_evaluator/__init__.py +0 -0
- nat/eval/trajectory_evaluator/evaluate.py +75 -0
- nat/eval/trajectory_evaluator/register.py +40 -0
- nat/eval/tunable_rag_evaluator/__init__.py +0 -0
- nat/eval/tunable_rag_evaluator/evaluate.py +242 -0
- nat/eval/tunable_rag_evaluator/register.py +52 -0
- nat/eval/usage_stats.py +41 -0
- nat/eval/utils/__init__.py +0 -0
- nat/eval/utils/eval_trace_ctx.py +89 -0
- nat/eval/utils/output_uploader.py +140 -0
- nat/eval/utils/tqdm_position_registry.py +40 -0
- nat/eval/utils/weave_eval.py +193 -0
- nat/experimental/__init__.py +0 -0
- nat/experimental/decorators/__init__.py +0 -0
- nat/experimental/decorators/experimental_warning_decorator.py +154 -0
- nat/experimental/test_time_compute/__init__.py +0 -0
- nat/experimental/test_time_compute/editing/__init__.py +0 -0
- nat/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +147 -0
- nat/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +204 -0
- nat/experimental/test_time_compute/editing/motivation_aware_summarization.py +107 -0
- nat/experimental/test_time_compute/functions/__init__.py +0 -0
- nat/experimental/test_time_compute/functions/execute_score_select_function.py +105 -0
- nat/experimental/test_time_compute/functions/plan_select_execute_function.py +228 -0
- nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +205 -0
- nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +146 -0
- nat/experimental/test_time_compute/models/__init__.py +0 -0
- nat/experimental/test_time_compute/models/editor_config.py +132 -0
- nat/experimental/test_time_compute/models/scoring_config.py +112 -0
- nat/experimental/test_time_compute/models/search_config.py +120 -0
- nat/experimental/test_time_compute/models/selection_config.py +154 -0
- nat/experimental/test_time_compute/models/stage_enums.py +43 -0
- nat/experimental/test_time_compute/models/strategy_base.py +67 -0
- nat/experimental/test_time_compute/models/tool_use_config.py +41 -0
- nat/experimental/test_time_compute/models/ttc_item.py +48 -0
- nat/experimental/test_time_compute/register.py +35 -0
- nat/experimental/test_time_compute/scoring/__init__.py +0 -0
- nat/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +168 -0
- nat/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +168 -0
- nat/experimental/test_time_compute/scoring/motivation_aware_scorer.py +111 -0
- nat/experimental/test_time_compute/search/__init__.py +0 -0
- nat/experimental/test_time_compute/search/multi_llm_planner.py +128 -0
- nat/experimental/test_time_compute/search/multi_query_retrieval_search.py +122 -0
- nat/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +128 -0
- nat/experimental/test_time_compute/selection/__init__.py +0 -0
- nat/experimental/test_time_compute/selection/best_of_n_selector.py +63 -0
- nat/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +131 -0
- nat/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +157 -0
- nat/experimental/test_time_compute/selection/llm_based_plan_selector.py +128 -0
- nat/experimental/test_time_compute/selection/threshold_selector.py +58 -0
- nat/front_ends/__init__.py +14 -0
- nat/front_ends/console/__init__.py +14 -0
- nat/front_ends/console/authentication_flow_handler.py +285 -0
- nat/front_ends/console/console_front_end_config.py +32 -0
- nat/front_ends/console/console_front_end_plugin.py +108 -0
- nat/front_ends/console/register.py +25 -0
- nat/front_ends/cron/__init__.py +14 -0
- nat/front_ends/fastapi/__init__.py +14 -0
- nat/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
- nat/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +27 -0
- nat/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +142 -0
- nat/front_ends/fastapi/dask_client_mixin.py +65 -0
- nat/front_ends/fastapi/fastapi_front_end_config.py +272 -0
- nat/front_ends/fastapi/fastapi_front_end_controller.py +68 -0
- nat/front_ends/fastapi/fastapi_front_end_plugin.py +247 -0
- nat/front_ends/fastapi/fastapi_front_end_plugin_worker.py +1257 -0
- nat/front_ends/fastapi/html_snippets/__init__.py +14 -0
- nat/front_ends/fastapi/html_snippets/auth_code_grant_success.py +35 -0
- nat/front_ends/fastapi/intermediate_steps_subscriber.py +80 -0
- nat/front_ends/fastapi/job_store.py +602 -0
- nat/front_ends/fastapi/main.py +64 -0
- nat/front_ends/fastapi/message_handler.py +344 -0
- nat/front_ends/fastapi/message_validator.py +351 -0
- nat/front_ends/fastapi/register.py +25 -0
- nat/front_ends/fastapi/response_helpers.py +195 -0
- nat/front_ends/fastapi/step_adaptor.py +319 -0
- nat/front_ends/fastapi/utils.py +57 -0
- nat/front_ends/mcp/__init__.py +14 -0
- nat/front_ends/mcp/introspection_token_verifier.py +73 -0
- nat/front_ends/mcp/mcp_front_end_config.py +90 -0
- nat/front_ends/mcp/mcp_front_end_plugin.py +113 -0
- nat/front_ends/mcp/mcp_front_end_plugin_worker.py +268 -0
- nat/front_ends/mcp/memory_profiler.py +320 -0
- nat/front_ends/mcp/register.py +27 -0
- nat/front_ends/mcp/tool_converter.py +290 -0
- nat/front_ends/register.py +21 -0
- nat/front_ends/simple_base/__init__.py +14 -0
- nat/front_ends/simple_base/simple_front_end_plugin_base.py +56 -0
- nat/llm/__init__.py +0 -0
- nat/llm/aws_bedrock_llm.py +69 -0
- nat/llm/azure_openai_llm.py +57 -0
- nat/llm/litellm_llm.py +69 -0
- nat/llm/nim_llm.py +58 -0
- nat/llm/openai_llm.py +54 -0
- nat/llm/register.py +27 -0
- nat/llm/utils/__init__.py +14 -0
- nat/llm/utils/env_config_value.py +93 -0
- nat/llm/utils/error.py +17 -0
- nat/llm/utils/thinking.py +215 -0
- nat/memory/__init__.py +20 -0
- nat/memory/interfaces.py +183 -0
- nat/memory/models.py +112 -0
- nat/meta/pypi.md +58 -0
- nat/object_store/__init__.py +20 -0
- nat/object_store/in_memory_object_store.py +76 -0
- nat/object_store/interfaces.py +84 -0
- nat/object_store/models.py +38 -0
- nat/object_store/register.py +19 -0
- nat/observability/__init__.py +14 -0
- nat/observability/exporter/__init__.py +14 -0
- nat/observability/exporter/base_exporter.py +449 -0
- nat/observability/exporter/exporter.py +78 -0
- nat/observability/exporter/file_exporter.py +33 -0
- nat/observability/exporter/processing_exporter.py +550 -0
- nat/observability/exporter/raw_exporter.py +52 -0
- nat/observability/exporter/span_exporter.py +308 -0
- nat/observability/exporter_manager.py +335 -0
- nat/observability/mixin/__init__.py +14 -0
- nat/observability/mixin/batch_config_mixin.py +26 -0
- nat/observability/mixin/collector_config_mixin.py +23 -0
- nat/observability/mixin/file_mixin.py +288 -0
- nat/observability/mixin/file_mode.py +23 -0
- nat/observability/mixin/redaction_config_mixin.py +42 -0
- nat/observability/mixin/resource_conflict_mixin.py +134 -0
- nat/observability/mixin/serialize_mixin.py +61 -0
- nat/observability/mixin/tagging_config_mixin.py +62 -0
- nat/observability/mixin/type_introspection_mixin.py +496 -0
- nat/observability/processor/__init__.py +14 -0
- nat/observability/processor/batching_processor.py +308 -0
- nat/observability/processor/callback_processor.py +42 -0
- nat/observability/processor/falsy_batch_filter_processor.py +55 -0
- nat/observability/processor/intermediate_step_serializer.py +28 -0
- nat/observability/processor/processor.py +74 -0
- nat/observability/processor/processor_factory.py +70 -0
- nat/observability/processor/redaction/__init__.py +24 -0
- nat/observability/processor/redaction/contextual_redaction_processor.py +125 -0
- nat/observability/processor/redaction/contextual_span_redaction_processor.py +66 -0
- nat/observability/processor/redaction/redaction_processor.py +177 -0
- nat/observability/processor/redaction/span_header_redaction_processor.py +92 -0
- nat/observability/processor/span_tagging_processor.py +68 -0
- nat/observability/register.py +114 -0
- nat/observability/utils/__init__.py +14 -0
- nat/observability/utils/dict_utils.py +236 -0
- nat/observability/utils/time_utils.py +31 -0
- nat/plugins/.namespace +1 -0
- nat/profiler/__init__.py +0 -0
- nat/profiler/calc/__init__.py +14 -0
- nat/profiler/calc/calc_runner.py +626 -0
- nat/profiler/calc/calculations.py +288 -0
- nat/profiler/calc/data_models.py +188 -0
- nat/profiler/calc/plot.py +345 -0
- nat/profiler/callbacks/__init__.py +0 -0
- nat/profiler/callbacks/agno_callback_handler.py +295 -0
- nat/profiler/callbacks/base_callback_class.py +20 -0
- nat/profiler/callbacks/langchain_callback_handler.py +297 -0
- nat/profiler/callbacks/llama_index_callback_handler.py +205 -0
- nat/profiler/callbacks/semantic_kernel_callback_handler.py +238 -0
- nat/profiler/callbacks/token_usage_base_model.py +27 -0
- nat/profiler/data_frame_row.py +51 -0
- nat/profiler/data_models.py +24 -0
- nat/profiler/decorators/__init__.py +0 -0
- nat/profiler/decorators/framework_wrapper.py +180 -0
- nat/profiler/decorators/function_tracking.py +411 -0
- nat/profiler/forecasting/__init__.py +0 -0
- nat/profiler/forecasting/config.py +18 -0
- nat/profiler/forecasting/model_trainer.py +75 -0
- nat/profiler/forecasting/models/__init__.py +22 -0
- nat/profiler/forecasting/models/forecasting_base_model.py +42 -0
- nat/profiler/forecasting/models/linear_model.py +197 -0
- nat/profiler/forecasting/models/random_forest_regressor.py +269 -0
- nat/profiler/inference_metrics_model.py +28 -0
- nat/profiler/inference_optimization/__init__.py +0 -0
- nat/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- nat/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +460 -0
- nat/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +258 -0
- nat/profiler/inference_optimization/data_models.py +386 -0
- nat/profiler/inference_optimization/experimental/__init__.py +0 -0
- nat/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +468 -0
- nat/profiler/inference_optimization/experimental/prefix_span_analysis.py +404 -0
- nat/profiler/inference_optimization/llm_metrics.py +212 -0
- nat/profiler/inference_optimization/prompt_caching.py +163 -0
- nat/profiler/inference_optimization/token_uniqueness.py +107 -0
- nat/profiler/inference_optimization/workflow_runtimes.py +72 -0
- nat/profiler/intermediate_property_adapter.py +102 -0
- nat/profiler/parameter_optimization/__init__.py +0 -0
- nat/profiler/parameter_optimization/optimizable_utils.py +93 -0
- nat/profiler/parameter_optimization/optimizer_runtime.py +67 -0
- nat/profiler/parameter_optimization/parameter_optimizer.py +153 -0
- nat/profiler/parameter_optimization/parameter_selection.py +107 -0
- nat/profiler/parameter_optimization/pareto_visualizer.py +380 -0
- nat/profiler/parameter_optimization/prompt_optimizer.py +384 -0
- nat/profiler/parameter_optimization/update_helpers.py +66 -0
- nat/profiler/profile_runner.py +478 -0
- nat/profiler/utils.py +186 -0
- nat/registry_handlers/__init__.py +0 -0
- nat/registry_handlers/local/__init__.py +0 -0
- nat/registry_handlers/local/local_handler.py +176 -0
- nat/registry_handlers/local/register_local.py +37 -0
- nat/registry_handlers/metadata_factory.py +60 -0
- nat/registry_handlers/package_utils.py +570 -0
- nat/registry_handlers/pypi/__init__.py +0 -0
- nat/registry_handlers/pypi/pypi_handler.py +248 -0
- nat/registry_handlers/pypi/register_pypi.py +40 -0
- nat/registry_handlers/register.py +20 -0
- nat/registry_handlers/registry_handler_base.py +157 -0
- nat/registry_handlers/rest/__init__.py +0 -0
- nat/registry_handlers/rest/register_rest.py +56 -0
- nat/registry_handlers/rest/rest_handler.py +236 -0
- nat/registry_handlers/schemas/__init__.py +0 -0
- nat/registry_handlers/schemas/headers.py +42 -0
- nat/registry_handlers/schemas/package.py +68 -0
- nat/registry_handlers/schemas/publish.py +68 -0
- nat/registry_handlers/schemas/pull.py +82 -0
- nat/registry_handlers/schemas/remove.py +36 -0
- nat/registry_handlers/schemas/search.py +91 -0
- nat/registry_handlers/schemas/status.py +47 -0
- nat/retriever/__init__.py +0 -0
- nat/retriever/interface.py +41 -0
- nat/retriever/milvus/__init__.py +14 -0
- nat/retriever/milvus/register.py +81 -0
- nat/retriever/milvus/retriever.py +228 -0
- nat/retriever/models.py +77 -0
- nat/retriever/nemo_retriever/__init__.py +14 -0
- nat/retriever/nemo_retriever/register.py +60 -0
- nat/retriever/nemo_retriever/retriever.py +190 -0
- nat/retriever/register.py +21 -0
- nat/runtime/__init__.py +14 -0
- nat/runtime/loader.py +220 -0
- nat/runtime/runner.py +292 -0
- nat/runtime/session.py +223 -0
- nat/runtime/user_metadata.py +130 -0
- nat/settings/__init__.py +0 -0
- nat/settings/global_settings.py +329 -0
- nat/test/.namespace +1 -0
- nat/tool/__init__.py +0 -0
- nat/tool/chat_completion.py +77 -0
- nat/tool/code_execution/README.md +151 -0
- nat/tool/code_execution/__init__.py +0 -0
- nat/tool/code_execution/code_sandbox.py +267 -0
- nat/tool/code_execution/local_sandbox/.gitignore +1 -0
- nat/tool/code_execution/local_sandbox/Dockerfile.sandbox +60 -0
- nat/tool/code_execution/local_sandbox/__init__.py +13 -0
- nat/tool/code_execution/local_sandbox/local_sandbox_server.py +198 -0
- nat/tool/code_execution/local_sandbox/sandbox.requirements.txt +6 -0
- nat/tool/code_execution/local_sandbox/start_local_sandbox.sh +50 -0
- nat/tool/code_execution/register.py +74 -0
- nat/tool/code_execution/test_code_execution_sandbox.py +414 -0
- nat/tool/code_execution/utils.py +100 -0
- nat/tool/datetime_tools.py +82 -0
- nat/tool/document_search.py +141 -0
- nat/tool/github_tools.py +450 -0
- nat/tool/memory_tools/__init__.py +0 -0
- nat/tool/memory_tools/add_memory_tool.py +79 -0
- nat/tool/memory_tools/delete_memory_tool.py +66 -0
- nat/tool/memory_tools/get_memory_tool.py +72 -0
- nat/tool/nvidia_rag.py +95 -0
- nat/tool/register.py +31 -0
- nat/tool/retriever.py +95 -0
- nat/tool/server_tools.py +66 -0
- nat/utils/__init__.py +0 -0
- nat/utils/callable_utils.py +70 -0
- nat/utils/data_models/__init__.py +0 -0
- nat/utils/data_models/schema_validator.py +58 -0
- nat/utils/debugging_utils.py +43 -0
- nat/utils/decorators.py +210 -0
- nat/utils/dump_distro_mapping.py +32 -0
- nat/utils/exception_handlers/__init__.py +0 -0
- nat/utils/exception_handlers/automatic_retries.py +342 -0
- nat/utils/exception_handlers/schemas.py +114 -0
- nat/utils/io/__init__.py +0 -0
- nat/utils/io/model_processing.py +28 -0
- nat/utils/io/yaml_tools.py +119 -0
- nat/utils/log_levels.py +25 -0
- nat/utils/log_utils.py +37 -0
- nat/utils/metadata_utils.py +74 -0
- nat/utils/optional_imports.py +142 -0
- nat/utils/producer_consumer_queue.py +178 -0
- nat/utils/reactive/__init__.py +0 -0
- nat/utils/reactive/base/__init__.py +0 -0
- nat/utils/reactive/base/observable_base.py +65 -0
- nat/utils/reactive/base/observer_base.py +55 -0
- nat/utils/reactive/base/subject_base.py +79 -0
- nat/utils/reactive/observable.py +59 -0
- nat/utils/reactive/observer.py +76 -0
- nat/utils/reactive/subject.py +131 -0
- nat/utils/reactive/subscription.py +49 -0
- nat/utils/settings/__init__.py +0 -0
- nat/utils/settings/global_settings.py +195 -0
- nat/utils/string_utils.py +38 -0
- nat/utils/type_converter.py +299 -0
- nat/utils/type_utils.py +488 -0
- nat/utils/url_utils.py +27 -0
- nvidia_nat-1.1.0a20251020.dist-info/METADATA +195 -0
- nvidia_nat-1.1.0a20251020.dist-info/RECORD +480 -0
- nvidia_nat-1.1.0a20251020.dist-info/WHEEL +5 -0
- nvidia_nat-1.1.0a20251020.dist-info/entry_points.txt +22 -0
- nvidia_nat-1.1.0a20251020.dist-info/licenses/LICENSE-3rd-party.txt +5478 -0
- nvidia_nat-1.1.0a20251020.dist-info/licenses/LICENSE.md +201 -0
- nvidia_nat-1.1.0a20251020.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,329 @@
|
|
|
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 json
|
|
17
|
+
import logging
|
|
18
|
+
import os
|
|
19
|
+
import typing
|
|
20
|
+
from collections.abc import Callable
|
|
21
|
+
from contextlib import contextmanager
|
|
22
|
+
from copy import deepcopy
|
|
23
|
+
|
|
24
|
+
from platformdirs import user_config_dir
|
|
25
|
+
from pydantic import ConfigDict
|
|
26
|
+
from pydantic import Discriminator
|
|
27
|
+
from pydantic import Tag
|
|
28
|
+
from pydantic import ValidationError
|
|
29
|
+
from pydantic import ValidationInfo
|
|
30
|
+
from pydantic import ValidatorFunctionWrapHandler
|
|
31
|
+
from pydantic import field_validator
|
|
32
|
+
|
|
33
|
+
from nat.cli.type_registry import GlobalTypeRegistry
|
|
34
|
+
from nat.cli.type_registry import RegisteredInfo
|
|
35
|
+
from nat.data_models.common import HashableBaseModel
|
|
36
|
+
from nat.data_models.common import TypedBaseModel
|
|
37
|
+
from nat.data_models.common import TypedBaseModelT
|
|
38
|
+
from nat.data_models.registry_handler import RegistryHandlerBaseConfig
|
|
39
|
+
|
|
40
|
+
logger = logging.getLogger(__name__)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Settings(HashableBaseModel):
|
|
44
|
+
|
|
45
|
+
model_config = ConfigDict(extra="forbid")
|
|
46
|
+
|
|
47
|
+
# Registry Handeler Configuration
|
|
48
|
+
channels: dict[str, RegistryHandlerBaseConfig] = {}
|
|
49
|
+
|
|
50
|
+
# Timezone fallback behavior
|
|
51
|
+
# Options:
|
|
52
|
+
# - "utc": default to UTC
|
|
53
|
+
# - "system": use the system's local timezone
|
|
54
|
+
fallback_timezone: typing.Literal["system", "utc"] = "utc"
|
|
55
|
+
|
|
56
|
+
_configuration_directory: typing.ClassVar[str]
|
|
57
|
+
_settings_changed_hooks: typing.ClassVar[list[Callable[[], None]]] = []
|
|
58
|
+
_settings_changed_hooks_active: bool = True
|
|
59
|
+
|
|
60
|
+
@field_validator("channels", mode="wrap")
|
|
61
|
+
@classmethod
|
|
62
|
+
def validate_components(cls, value: typing.Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo):
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
return handler(value)
|
|
66
|
+
except ValidationError as err:
|
|
67
|
+
|
|
68
|
+
for e in err.errors():
|
|
69
|
+
if e['type'] == 'union_tag_invalid' and len(e['loc']) > 0:
|
|
70
|
+
requested_type = e['loc'][0]
|
|
71
|
+
|
|
72
|
+
if (info.field_name == "channels"):
|
|
73
|
+
registered_keys = GlobalTypeRegistry.get().get_registered_registry_handlers()
|
|
74
|
+
else:
|
|
75
|
+
assert False, f"Unknown field name {info.field_name} in validator"
|
|
76
|
+
|
|
77
|
+
# Check and see if the there are multiple full types which match this short type
|
|
78
|
+
matching_keys = [k for k in registered_keys if k.local_name == requested_type]
|
|
79
|
+
|
|
80
|
+
assert len(matching_keys) != 1, "Exact match should have been found. Contact developers"
|
|
81
|
+
|
|
82
|
+
matching_key_names = [x.full_type for x in matching_keys]
|
|
83
|
+
registered_key_names = [x.full_type for x in registered_keys]
|
|
84
|
+
|
|
85
|
+
if (len(matching_keys) == 0):
|
|
86
|
+
# This is a case where the requested type is not found. Show a helpful message about what is
|
|
87
|
+
# available
|
|
88
|
+
raise ValueError(
|
|
89
|
+
f"Requested {info.field_name} type `{requested_type}` not found. "
|
|
90
|
+
"Have you ensured the necessary package has been installed with `uv pip install`?"
|
|
91
|
+
"\nAvailable {} names:\n - {}".format(info.field_name,
|
|
92
|
+
'\n - '.join(registered_key_names))) from err
|
|
93
|
+
|
|
94
|
+
# This is a case where the requested type is ambiguous.
|
|
95
|
+
raise ValueError(f"Requested {info.field_name} type `{requested_type}` is ambiguous. " +
|
|
96
|
+
f"Matched multiple {info.field_name} by their local name: {matching_key_names}. " +
|
|
97
|
+
f"Please use the fully qualified {info.field_name} name." +
|
|
98
|
+
"\nAvailable {} names:\n - {}".format(info.field_name,
|
|
99
|
+
'\n - '.join(registered_key_names))) from err
|
|
100
|
+
|
|
101
|
+
raise
|
|
102
|
+
|
|
103
|
+
@classmethod
|
|
104
|
+
def rebuild_annotations(cls):
|
|
105
|
+
|
|
106
|
+
def compute_annotation(cls: type[TypedBaseModelT], registrations: list[RegisteredInfo[TypedBaseModelT]]):
|
|
107
|
+
|
|
108
|
+
while (len(registrations) < 2):
|
|
109
|
+
registrations.append(RegisteredInfo[TypedBaseModelT](full_type=f"_ignore/{len(registrations)}",
|
|
110
|
+
config_type=cls))
|
|
111
|
+
|
|
112
|
+
short_names: dict[str, int] = {}
|
|
113
|
+
type_list: list[tuple[str, type[TypedBaseModelT]]] = []
|
|
114
|
+
|
|
115
|
+
# For all keys in the list, split the key by / and increment the count of the last element
|
|
116
|
+
for key in registrations:
|
|
117
|
+
short_names[key.local_name] = short_names.get(key.local_name, 0) + 1
|
|
118
|
+
|
|
119
|
+
type_list.append((key.full_type, key.config_type))
|
|
120
|
+
|
|
121
|
+
# Now loop again and if the short name is unique, then create two entries, for the short and full name
|
|
122
|
+
for key in registrations:
|
|
123
|
+
|
|
124
|
+
if (short_names[key.local_name] == 1):
|
|
125
|
+
type_list.append((key.local_name, key.config_type))
|
|
126
|
+
|
|
127
|
+
return typing.Union[*tuple(typing.Annotated[x_type, Tag(x_id)] for x_id, x_type in type_list)]
|
|
128
|
+
|
|
129
|
+
RegistryHandlerAnnotation = dict[
|
|
130
|
+
str,
|
|
131
|
+
typing.Annotated[compute_annotation(RegistryHandlerBaseConfig,
|
|
132
|
+
GlobalTypeRegistry.get().get_registered_registry_handlers()),
|
|
133
|
+
Discriminator(TypedBaseModel.discriminator)]]
|
|
134
|
+
|
|
135
|
+
should_rebuild = False
|
|
136
|
+
|
|
137
|
+
channels_field = cls.model_fields.get("channels")
|
|
138
|
+
if channels_field is not None and channels_field.annotation != RegistryHandlerAnnotation:
|
|
139
|
+
channels_field.annotation = RegistryHandlerAnnotation
|
|
140
|
+
should_rebuild = True
|
|
141
|
+
|
|
142
|
+
if (should_rebuild):
|
|
143
|
+
cls.model_rebuild(force=True)
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def channel_names(self) -> list:
|
|
147
|
+
return list(self.channels.keys())
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def configuration_directory(self) -> str:
|
|
151
|
+
return self._configuration_directory
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
def configuration_file(self) -> str:
|
|
155
|
+
return os.path.join(self.configuration_directory, "config.json")
|
|
156
|
+
|
|
157
|
+
@staticmethod
|
|
158
|
+
def from_file():
|
|
159
|
+
|
|
160
|
+
configuration_directory = os.getenv("NAT_CONFIG_DIR", user_config_dir(appname="nat"))
|
|
161
|
+
|
|
162
|
+
if not os.path.exists(configuration_directory):
|
|
163
|
+
os.makedirs(configuration_directory, exist_ok=True)
|
|
164
|
+
|
|
165
|
+
configuration_file = os.path.join(configuration_directory, "config.json")
|
|
166
|
+
|
|
167
|
+
file_path = os.path.join(configuration_directory, "config.json")
|
|
168
|
+
|
|
169
|
+
if (not os.path.exists(configuration_file)):
|
|
170
|
+
loaded_config = {}
|
|
171
|
+
else:
|
|
172
|
+
with open(file_path, encoding="utf-8") as f:
|
|
173
|
+
try:
|
|
174
|
+
loaded_config = json.load(f)
|
|
175
|
+
except Exception as e:
|
|
176
|
+
logger.exception("Error loading configuration file %s: %s", file_path, e)
|
|
177
|
+
loaded_config = {}
|
|
178
|
+
|
|
179
|
+
settings = Settings(**loaded_config)
|
|
180
|
+
settings.set_configuration_directory(configuration_directory)
|
|
181
|
+
return settings
|
|
182
|
+
|
|
183
|
+
def set_configuration_directory(self, directory: str, remove: bool = False) -> None:
|
|
184
|
+
if (remove):
|
|
185
|
+
if os.path.exists(self.configuration_directory):
|
|
186
|
+
os.rmdir(self.configuration_directory)
|
|
187
|
+
self.__class__._configuration_directory = directory
|
|
188
|
+
|
|
189
|
+
def reset_configuration_directory(self, remove: bool = False) -> None:
|
|
190
|
+
if (remove):
|
|
191
|
+
if os.path.exists(self.configuration_directory):
|
|
192
|
+
os.rmdir(self.configuration_directory)
|
|
193
|
+
self._configuration_directory = os.getenv("NAT_CONFIG_DIR", user_config_dir(appname="nat"))
|
|
194
|
+
|
|
195
|
+
def _save_settings(self) -> None:
|
|
196
|
+
|
|
197
|
+
if not os.path.exists(self.configuration_directory):
|
|
198
|
+
os.mkdir(self.configuration_directory)
|
|
199
|
+
|
|
200
|
+
with open(self.configuration_file, mode="w", encoding="utf-8") as f:
|
|
201
|
+
f.write(self.model_dump_json(indent=4, by_alias=True, serialize_as_any=True))
|
|
202
|
+
|
|
203
|
+
self._settings_changed()
|
|
204
|
+
|
|
205
|
+
def update_settings(self, config_obj: "dict | Settings"):
|
|
206
|
+
self._update_settings(config_obj)
|
|
207
|
+
|
|
208
|
+
def _update_settings(self, config_obj: "dict | Settings"):
|
|
209
|
+
|
|
210
|
+
if isinstance(config_obj, Settings):
|
|
211
|
+
config_obj = config_obj.model_dump(serialize_as_any=True, by_alias=True)
|
|
212
|
+
|
|
213
|
+
self._revalidate(config_dict=config_obj)
|
|
214
|
+
|
|
215
|
+
self._save_settings()
|
|
216
|
+
|
|
217
|
+
def _revalidate(self, config_dict) -> bool:
|
|
218
|
+
|
|
219
|
+
try:
|
|
220
|
+
validated_data = self.__class__(**config_dict)
|
|
221
|
+
|
|
222
|
+
for field in validated_data.model_fields:
|
|
223
|
+
match field:
|
|
224
|
+
case "channels":
|
|
225
|
+
self.channels = validated_data.channels
|
|
226
|
+
case "fallback_timezone":
|
|
227
|
+
self.fallback_timezone = validated_data.fallback_timezone
|
|
228
|
+
case _:
|
|
229
|
+
raise ValueError(f"Encountered invalid model field: {field}")
|
|
230
|
+
|
|
231
|
+
return True
|
|
232
|
+
|
|
233
|
+
except Exception as e:
|
|
234
|
+
logger.exception("Unable to validate user settings configuration: %s", e)
|
|
235
|
+
return False
|
|
236
|
+
|
|
237
|
+
def print_channel_settings(self, channel_type: str | None = None) -> None:
|
|
238
|
+
|
|
239
|
+
import yaml
|
|
240
|
+
|
|
241
|
+
remote_channels = self.model_dump(serialize_as_any=True, by_alias=True)
|
|
242
|
+
|
|
243
|
+
if (not remote_channels or not remote_channels.get("channels")):
|
|
244
|
+
logger.warning("No configured channels to list.")
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
if (channel_type is not None):
|
|
248
|
+
filter_channels = []
|
|
249
|
+
for channel, settings in remote_channels.items():
|
|
250
|
+
if (settings["type"] != channel_type):
|
|
251
|
+
filter_channels.append(channel)
|
|
252
|
+
for channel in filter_channels:
|
|
253
|
+
del remote_channels[channel]
|
|
254
|
+
|
|
255
|
+
if (remote_channels):
|
|
256
|
+
logger.info(yaml.dump(remote_channels, allow_unicode=True, default_flow_style=False))
|
|
257
|
+
|
|
258
|
+
def override_settings(self, config_file: str) -> "Settings":
|
|
259
|
+
|
|
260
|
+
from nat.utils.io.yaml_tools import yaml_load
|
|
261
|
+
|
|
262
|
+
override_settings_dict = yaml_load(config_file)
|
|
263
|
+
|
|
264
|
+
settings_dict = self.model_dump()
|
|
265
|
+
updated_settings = {**override_settings_dict, **settings_dict}
|
|
266
|
+
self._update_settings(config_obj=updated_settings)
|
|
267
|
+
|
|
268
|
+
return self
|
|
269
|
+
|
|
270
|
+
def _settings_changed(self):
|
|
271
|
+
|
|
272
|
+
if (not self._settings_changed_hooks_active):
|
|
273
|
+
return
|
|
274
|
+
|
|
275
|
+
for hook in self._settings_changed_hooks:
|
|
276
|
+
hook()
|
|
277
|
+
|
|
278
|
+
@contextmanager
|
|
279
|
+
def pause_settings_changed_hooks(self):
|
|
280
|
+
|
|
281
|
+
self._settings_changed_hooks_active = False
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
yield
|
|
285
|
+
finally:
|
|
286
|
+
self._settings_changed_hooks_active = True
|
|
287
|
+
|
|
288
|
+
# Ensure that the registration changed hooks are called
|
|
289
|
+
self._settings_changed()
|
|
290
|
+
|
|
291
|
+
def add_settings_changed_hook(self, cb: Callable[[], None]) -> None:
|
|
292
|
+
|
|
293
|
+
self._settings_changed_hooks.append(cb)
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
GlobalTypeRegistry.get().add_registration_changed_hook(lambda: Settings.rebuild_annotations())
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class GlobalSettings:
|
|
300
|
+
|
|
301
|
+
_global_settings: Settings | None = None
|
|
302
|
+
|
|
303
|
+
@staticmethod
|
|
304
|
+
def get() -> Settings:
|
|
305
|
+
|
|
306
|
+
if (GlobalSettings._global_settings is None):
|
|
307
|
+
from nat.runtime.loader import PluginTypes
|
|
308
|
+
from nat.runtime.loader import discover_and_register_plugins
|
|
309
|
+
|
|
310
|
+
discover_and_register_plugins(PluginTypes.REGISTRY_HANDLER)
|
|
311
|
+
|
|
312
|
+
GlobalSettings._global_settings = Settings.from_file()
|
|
313
|
+
|
|
314
|
+
return GlobalSettings._global_settings
|
|
315
|
+
|
|
316
|
+
@staticmethod
|
|
317
|
+
@contextmanager
|
|
318
|
+
def push():
|
|
319
|
+
|
|
320
|
+
saved = GlobalSettings.get()
|
|
321
|
+
settings = deepcopy(saved)
|
|
322
|
+
|
|
323
|
+
try:
|
|
324
|
+
GlobalSettings._global_settings = settings
|
|
325
|
+
|
|
326
|
+
yield settings
|
|
327
|
+
finally:
|
|
328
|
+
GlobalSettings._global_settings = saved
|
|
329
|
+
GlobalSettings._global_settings._settings_changed()
|
nat/test/.namespace
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Note: This is a python namespace package and this directory should remain empty. Do NOT add a `__init__.py` file or any other files to this directory. This file is also needed to ensure the directory exists in git.
|
nat/tool/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
Simple Completion Function for NAT
|
|
17
|
+
|
|
18
|
+
This module provides a simple completion function that can handle
|
|
19
|
+
natural language queries and perform basic text completion tasks.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from pydantic import Field
|
|
23
|
+
|
|
24
|
+
from nat.builder.builder import Builder
|
|
25
|
+
from nat.builder.framework_enum import LLMFrameworkEnum
|
|
26
|
+
from nat.cli.register_workflow import register_function
|
|
27
|
+
from nat.data_models.component_ref import LLMRef
|
|
28
|
+
from nat.data_models.function import FunctionBaseConfig
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ChatCompletionConfig(FunctionBaseConfig, name="chat_completion"):
|
|
32
|
+
"""Configuration for the Chat Completion Function."""
|
|
33
|
+
|
|
34
|
+
system_prompt: str = Field(("You are a helpful AI assistant. Provide clear, accurate, and helpful "
|
|
35
|
+
"responses to user queries. You can give general advice, recommendations, "
|
|
36
|
+
"tips, and engage in conversation. Be helpful and informative."),
|
|
37
|
+
description="The system prompt to use for chat completion.")
|
|
38
|
+
|
|
39
|
+
llm_name: LLMRef = Field(description="The LLM to use for generating responses.")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@register_function(config_type=ChatCompletionConfig)
|
|
43
|
+
async def register_chat_completion(config: ChatCompletionConfig, builder: Builder):
|
|
44
|
+
"""Registers a chat completion function that can handle natural language queries."""
|
|
45
|
+
|
|
46
|
+
# Get the LLM from the builder context using the configured LLM reference
|
|
47
|
+
# Use LangChain/LangGraph framework wrapper since we're using LangChain/LangGraph-based LLM
|
|
48
|
+
llm = await builder.get_llm(config.llm_name, wrapper_type=LLMFrameworkEnum.LANGCHAIN)
|
|
49
|
+
|
|
50
|
+
async def _chat_completion(query: str) -> str:
|
|
51
|
+
"""A simple chat completion function that responds to natural language queries.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
query: The user's natural language query
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
A helpful response to the query
|
|
58
|
+
"""
|
|
59
|
+
try:
|
|
60
|
+
# Create a simple prompt with the system message and user query
|
|
61
|
+
prompt = f"{config.system_prompt}\n\nUser: {query}\n\nAssistant:"
|
|
62
|
+
|
|
63
|
+
# Generate response using the LLM
|
|
64
|
+
response = await llm.ainvoke(prompt)
|
|
65
|
+
|
|
66
|
+
if isinstance(response, str):
|
|
67
|
+
return response
|
|
68
|
+
|
|
69
|
+
return response.text()
|
|
70
|
+
|
|
71
|
+
except Exception as e:
|
|
72
|
+
# Fallback response if LLM call fails
|
|
73
|
+
return (f"I apologize, but I encountered an error while processing your "
|
|
74
|
+
f"query: '{query}'. Please try rephrasing your question or try "
|
|
75
|
+
f"again later. Error: {str(e)}")
|
|
76
|
+
|
|
77
|
+
yield _chat_completion
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
3
|
+
SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
|
|
5
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
you may not use this file except in compliance with the License.
|
|
7
|
+
You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
See the License for the specific language governing permissions and
|
|
15
|
+
limitations under the License.
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
# Code Execution Sandbox
|
|
19
|
+
|
|
20
|
+
A secure, containerized Python code execution environment that allows safe execution of Python code with comprehensive error handling and debugging capabilities.
|
|
21
|
+
|
|
22
|
+
## Overview
|
|
23
|
+
|
|
24
|
+
The Code Execution Sandbox provides:
|
|
25
|
+
- **Secure code execution** in isolated Docker containers
|
|
26
|
+
- **Multiple input formats** including raw code, dictionary format, and markdown
|
|
27
|
+
- **Dependency management** with pre-installed libraries
|
|
28
|
+
- **Flexible configuration** with customizable timeouts and output limits
|
|
29
|
+
- **Robust debugging** with extensive logging and error reporting
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Step 1: Start the Sandbox Server
|
|
34
|
+
|
|
35
|
+
Navigate to the local sandbox directory and start the server:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd src/nat/tool/code_execution/local_sandbox
|
|
39
|
+
./start_local_sandbox.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The script will:
|
|
43
|
+
- Build the Docker image if it doesn't exist
|
|
44
|
+
- Start the sandbox server on port 6000
|
|
45
|
+
- Mount your working directory for file operations
|
|
46
|
+
|
|
47
|
+
#### Advanced Usage:
|
|
48
|
+
```bash
|
|
49
|
+
# Custom container name
|
|
50
|
+
./start_local_sandbox.sh my-sandbox
|
|
51
|
+
|
|
52
|
+
# Custom output directory
|
|
53
|
+
./start_local_sandbox.sh my-sandbox /path/to/output
|
|
54
|
+
|
|
55
|
+
# Using environment variable
|
|
56
|
+
export OUTPUT_DATA_PATH=/path/to/output
|
|
57
|
+
./start_local_sandbox.sh
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Step 2: Test the Installation
|
|
61
|
+
|
|
62
|
+
Run the comprehensive test suite to verify everything is working:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
cd src/nat/tool/code_execution
|
|
66
|
+
pytest test_code_execution_sandbox.py
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Note: a running instance of a local sandbox is required.
|
|
70
|
+
|
|
71
|
+
## Using the Code Execution Tool
|
|
72
|
+
|
|
73
|
+
### Basic Usage
|
|
74
|
+
|
|
75
|
+
The sandbox accepts HTTP POST requests to `http://localhost:6000/execute` with JSON payloads:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
curl -X POST \
|
|
79
|
+
-H "Content-Type: application/json" \
|
|
80
|
+
-d '{
|
|
81
|
+
"generated_code": "print(\"Hello, World!\")",
|
|
82
|
+
"timeout": 30,
|
|
83
|
+
"language": "python"
|
|
84
|
+
}' \
|
|
85
|
+
http://localhost:6000/execute
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Supported Input Formats
|
|
89
|
+
|
|
90
|
+
#### 1. Raw Python Code
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"generated_code": "import numpy as np\nprint(np.array([1, 2, 3]))",
|
|
94
|
+
"timeout": 30,
|
|
95
|
+
"language": "python"
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### 2. Dictionary Format
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"generated_code": "{'generated_code': 'print(\"Hello from dict format\")'}",
|
|
103
|
+
"timeout": 30,
|
|
104
|
+
"language": "python"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
#### 3. Markdown Code Blocks
|
|
109
|
+
```json
|
|
110
|
+
{
|
|
111
|
+
"generated_code": "```python\nprint('Hello from markdown')\n```",
|
|
112
|
+
"timeout": 30,
|
|
113
|
+
"language": "python"
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Response Format
|
|
118
|
+
|
|
119
|
+
The sandbox returns JSON responses with the following structure:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"process_status": "completed|error|timeout",
|
|
124
|
+
"stdout": "Standard output content",
|
|
125
|
+
"stderr": "Standard error content"
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Configuration Options
|
|
130
|
+
|
|
131
|
+
### Sandbox Configuration
|
|
132
|
+
|
|
133
|
+
- **URI**: Default `http://127.0.0.1:6000`
|
|
134
|
+
- **Timeout**: Default 10 seconds (configurable)
|
|
135
|
+
- **Max Output Characters**: Default 1000 characters
|
|
136
|
+
- **Memory Limit**: 10GB (configurable in Docker)
|
|
137
|
+
- **Working Directory**: Mounted volume for file operations
|
|
138
|
+
|
|
139
|
+
### Environment Variables
|
|
140
|
+
|
|
141
|
+
- `OUTPUT_DATA_PATH`: Custom path for file operations
|
|
142
|
+
- `SANDBOX_HOST`: Custom sandbox host
|
|
143
|
+
- `SANDBOX_PORT`: Custom sandbox port
|
|
144
|
+
|
|
145
|
+
## Security Considerations
|
|
146
|
+
|
|
147
|
+
- **Isolated execution**: All code runs in Docker containers
|
|
148
|
+
- **Resource limits**: Memory and CPU limits prevent resource exhaustion
|
|
149
|
+
- **Network isolation**: Containers have limited network access
|
|
150
|
+
- **File system isolation**: Mounted volumes provide controlled file access
|
|
151
|
+
- **Process isolation**: Each execution runs in a separate process
|
|
File without changes
|