nvidia-nat 1.2.0rc5__py3-none-any.whl → 1.2.0rc7__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 → nat}/agent/react_agent/agent.py +12 -12
- {aiq → nat}/agent/react_agent/register.py +20 -20
- {aiq → nat}/agent/reasoning_agent/reasoning_agent.py +14 -14
- {aiq → nat}/agent/rewoo_agent/agent.py +7 -7
- {aiq → nat}/agent/rewoo_agent/prompt.py +11 -12
- {aiq → nat}/agent/rewoo_agent/register.py +47 -49
- {aiq → nat}/agent/tool_calling_agent/agent.py +4 -4
- {aiq → nat}/agent/tool_calling_agent/register.py +8 -8
- {aiq → nat}/authentication/api_key/api_key_auth_provider.py +6 -6
- {aiq → nat}/authentication/api_key/api_key_auth_provider_config.py +5 -5
- {aiq → nat}/authentication/api_key/register.py +4 -4
- {aiq → nat}/authentication/http_basic_auth/http_basic_auth_provider.py +10 -10
- {aiq → nat}/authentication/http_basic_auth/register.py +4 -4
- {aiq → nat}/authentication/interfaces.py +6 -6
- {aiq → nat}/authentication/oauth2/oauth2_auth_code_flow_provider.py +11 -11
- {aiq → nat}/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +1 -1
- {aiq → nat}/authentication/oauth2/register.py +4 -4
- {aiq → nat}/authentication/register.py +3 -3
- {aiq → nat}/builder/builder.py +30 -30
- {aiq → nat}/builder/component_utils.py +23 -23
- {aiq → nat}/builder/context.py +35 -29
- {aiq → nat}/builder/embedder.py +1 -1
- {aiq → nat}/builder/eval_builder.py +13 -13
- {aiq → nat}/builder/evaluator.py +3 -3
- {aiq → nat}/builder/front_end.py +11 -11
- {aiq → nat}/builder/function.py +8 -8
- {aiq → nat}/builder/function_base.py +6 -6
- {aiq → nat}/builder/function_info.py +3 -3
- {aiq → nat}/builder/intermediate_step_manager.py +13 -13
- {aiq → nat}/builder/llm.py +1 -1
- {aiq → nat}/builder/retriever.py +1 -1
- {aiq → nat}/builder/user_interaction_manager.py +14 -10
- {aiq → nat}/builder/workflow.py +25 -25
- {aiq → nat}/builder/workflow_builder.py +86 -86
- {aiq → nat}/cli/cli_utils/config_override.py +2 -2
- {aiq → nat}/cli/cli_utils/validation.py +4 -4
- {aiq → nat}/cli/commands/configure/channel/add.py +2 -2
- {aiq → nat}/cli/commands/configure/channel/channel.py +4 -6
- {aiq → nat}/cli/commands/configure/channel/remove.py +2 -2
- {aiq → nat}/cli/commands/configure/channel/update.py +2 -2
- {aiq → nat}/cli/commands/configure/configure.py +3 -3
- {aiq → nat}/cli/commands/evaluate.py +3 -3
- {aiq → nat}/cli/commands/info/info.py +5 -7
- {aiq → nat}/cli/commands/info/list_channels.py +1 -1
- {aiq → nat}/cli/commands/info/list_components.py +14 -14
- {aiq → nat}/cli/commands/info/list_mcp.py +106 -15
- {aiq → nat}/cli/commands/registry/publish.py +9 -9
- {aiq → nat}/cli/commands/registry/pull.py +10 -10
- {aiq → nat}/cli/commands/registry/registry.py +5 -7
- {aiq → nat}/cli/commands/registry/remove.py +8 -8
- {aiq → nat}/cli/commands/registry/search.py +15 -15
- {aiq → nat}/cli/commands/sizing/calc.py +3 -3
- {aiq → nat}/cli/commands/start.py +15 -15
- {aiq → nat}/cli/commands/uninstall.py +5 -5
- {aiq → nat}/cli/commands/validate.py +1 -1
- {aiq → nat}/cli/commands/workflow/templates/pyproject.toml.j2 +4 -4
- {aiq → nat}/cli/commands/workflow/templates/workflow.py.j2 +4 -4
- {aiq → nat}/cli/commands/workflow/workflow.py +3 -3
- {aiq → nat}/cli/commands/workflow/workflow_commands.py +15 -11
- {aiq → nat}/cli/entrypoint.py +6 -6
- {aiq → nat}/cli/main.py +15 -2
- {aiq → nat}/cli/register_workflow.py +70 -70
- {aiq → nat}/cli/type_registry.py +82 -82
- {aiq → nat}/data_models/api_server.py +121 -99
- {aiq → nat}/data_models/authentication.py +2 -2
- {aiq → nat}/data_models/component.py +5 -1
- {aiq → nat}/data_models/component_ref.py +12 -12
- {aiq → nat}/data_models/config.py +17 -13
- {aiq → nat}/data_models/dataset_handler.py +58 -12
- {aiq → nat}/data_models/discovery_metadata.py +36 -66
- {aiq → nat}/data_models/evaluate.py +9 -9
- {aiq → nat}/data_models/intermediate_step.py +7 -7
- {aiq → nat}/data_models/retriever.py +2 -2
- {aiq → nat}/data_models/span.py +10 -7
- {aiq → nat}/data_models/step_adaptor.py +1 -1
- {aiq → nat}/data_models/telemetry_exporter.py +2 -2
- {aiq → nat}/embedder/nim_embedder.py +5 -5
- {aiq → nat}/embedder/openai_embedder.py +5 -5
- {aiq/retriever → nat/embedder}/register.py +2 -2
- {aiq → nat}/eval/config.py +4 -4
- {aiq → nat}/eval/dataset_handler/dataset_downloader.py +1 -1
- {aiq → nat}/eval/dataset_handler/dataset_filter.py +1 -1
- {aiq → nat}/eval/dataset_handler/dataset_handler.py +127 -14
- {aiq → nat}/eval/evaluate.py +38 -34
- {aiq → nat}/eval/evaluator/base_evaluator.py +9 -5
- {aiq → nat}/eval/evaluator/evaluator_model.py +4 -4
- {aiq → nat}/eval/intermediate_step_adapter.py +2 -2
- {aiq → nat}/eval/rag_evaluator/evaluate.py +8 -8
- {aiq → nat}/eval/rag_evaluator/register.py +7 -7
- {aiq → nat}/eval/remote_workflow.py +8 -8
- {aiq → nat}/eval/runners/config.py +2 -2
- {aiq → nat}/eval/runners/multi_eval_runner.py +4 -4
- {aiq → nat}/eval/runtime_event_subscriber.py +3 -3
- {aiq → nat}/eval/swe_bench_evaluator/evaluate.py +6 -6
- {aiq → nat}/eval/swe_bench_evaluator/register.py +4 -4
- {aiq → nat}/eval/trajectory_evaluator/evaluate.py +5 -5
- {aiq → nat}/eval/trajectory_evaluator/register.py +5 -5
- {aiq → nat}/eval/tunable_rag_evaluator/evaluate.py +3 -3
- {aiq → nat}/eval/tunable_rag_evaluator/register.py +6 -6
- {aiq → nat}/eval/utils/output_uploader.py +1 -1
- {aiq → nat}/eval/utils/weave_eval.py +6 -6
- {aiq → nat}/experimental/decorators/experimental_warning_decorator.py +6 -2
- {aiq → nat}/experimental/test_time_compute/editing/iterative_plan_refinement_editor.py +10 -10
- {aiq → nat}/experimental/test_time_compute/editing/llm_as_a_judge_editor.py +10 -10
- {aiq → nat}/experimental/test_time_compute/editing/motivation_aware_summarization.py +10 -10
- {aiq → nat}/experimental/test_time_compute/functions/execute_score_select_function.py +10 -10
- {aiq → nat}/experimental/test_time_compute/functions/plan_select_execute_function.py +17 -17
- aiq/experimental/test_time_compute/functions/its_tool_orchestration_function.py → nat/experimental/test_time_compute/functions/ttc_tool_orchestration_function.py +12 -12
- aiq/experimental/test_time_compute/functions/its_tool_wrapper_function.py → nat/experimental/test_time_compute/functions/ttc_tool_wrapper_function.py +10 -10
- {aiq → nat}/experimental/test_time_compute/models/editor_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/scoring_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/search_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/selection_config.py +2 -2
- {aiq → nat}/experimental/test_time_compute/models/strategy_base.py +4 -4
- {aiq → nat}/experimental/test_time_compute/register.py +2 -2
- {aiq → nat}/experimental/test_time_compute/scoring/llm_based_agent_scorer.py +11 -11
- {aiq → nat}/experimental/test_time_compute/scoring/llm_based_plan_scorer.py +11 -11
- {aiq → nat}/experimental/test_time_compute/scoring/motivation_aware_scorer.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/multi_llm_planner.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/multi_query_retrieval_search.py +10 -10
- {aiq → nat}/experimental/test_time_compute/search/single_shot_multi_plan_planner.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/best_of_n_selector.py +7 -7
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_agent_output_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_output_merging_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/llm_based_plan_selector.py +11 -11
- {aiq → nat}/experimental/test_time_compute/selection/threshold_selector.py +7 -7
- {aiq → nat}/front_ends/console/authentication_flow_handler.py +6 -6
- {aiq → nat}/front_ends/console/console_front_end_config.py +2 -2
- {aiq → nat}/front_ends/console/console_front_end_plugin.py +9 -9
- {aiq → nat}/front_ends/console/register.py +5 -5
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +4 -4
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +6 -6
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_config.py +22 -15
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_plugin.py +10 -10
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_plugin_worker.py +110 -115
- {aiq → nat}/front_ends/fastapi/intermediate_steps_subscriber.py +10 -10
- {aiq → nat}/front_ends/fastapi/main.py +8 -8
- {aiq → nat}/front_ends/fastapi/message_handler.py +58 -36
- {aiq → nat}/front_ends/fastapi/message_validator.py +55 -48
- {aiq → nat}/front_ends/fastapi/register.py +5 -5
- {aiq → nat}/front_ends/fastapi/response_helpers.py +26 -26
- {aiq → nat}/front_ends/fastapi/step_adaptor.py +35 -37
- {aiq → nat}/front_ends/mcp/mcp_front_end_config.py +12 -8
- nat/front_ends/mcp/mcp_front_end_plugin.py +81 -0
- nat/front_ends/mcp/mcp_front_end_plugin_worker.py +143 -0
- {aiq → nat}/front_ends/mcp/register.py +5 -5
- {aiq → nat}/front_ends/mcp/tool_converter.py +20 -21
- {aiq → nat}/front_ends/simple_base/simple_front_end_plugin_base.py +6 -6
- {aiq → nat}/llm/aws_bedrock_llm.py +5 -5
- {aiq → nat}/llm/nim_llm.py +5 -5
- {aiq → nat}/llm/openai_llm.py +5 -5
- {aiq → nat}/memory/__init__.py +2 -2
- nat/meta/pypi.md +58 -0
- {aiq → nat}/object_store/__init__.py +2 -2
- {aiq → nat}/object_store/in_memory_object_store.py +6 -6
- {aiq → nat}/observability/exporter/base_exporter.py +9 -9
- {aiq → nat}/observability/exporter/exporter.py +1 -1
- {aiq → nat}/observability/exporter/file_exporter.py +6 -6
- {aiq → nat}/observability/exporter/processing_exporter.py +9 -9
- {aiq → nat}/observability/exporter/raw_exporter.py +4 -4
- {aiq → nat}/observability/exporter/span_exporter.py +57 -34
- {aiq → nat}/observability/exporter_manager.py +6 -6
- {aiq → nat}/observability/mixin/file_mixin.py +2 -2
- {aiq → nat}/observability/processor/batching_processor.py +1 -1
- {aiq → nat}/observability/processor/callback_processor.py +1 -1
- {aiq → nat}/observability/processor/intermediate_step_serializer.py +4 -4
- {aiq → nat}/observability/processor/processor.py +1 -1
- {aiq → nat}/observability/register.py +7 -7
- {aiq → nat}/profiler/calc/calc_runner.py +18 -18
- {aiq → nat}/profiler/calc/calculations.py +3 -3
- {aiq → nat}/profiler/calc/plot.py +2 -2
- {aiq → nat}/profiler/callbacks/agno_callback_handler.py +14 -14
- {aiq → nat}/profiler/callbacks/langchain_callback_handler.py +11 -11
- {aiq → nat}/profiler/callbacks/llama_index_callback_handler.py +12 -12
- {aiq → nat}/profiler/callbacks/semantic_kernel_callback_handler.py +11 -11
- {aiq → nat}/profiler/data_models.py +2 -2
- {aiq → nat}/profiler/decorators/framework_wrapper.py +6 -6
- {aiq → nat}/profiler/decorators/function_tracking.py +10 -10
- {aiq → nat}/profiler/forecasting/model_trainer.py +5 -5
- {aiq → nat}/profiler/forecasting/models/linear_model.py +5 -4
- {aiq → nat}/profiler/forecasting/models/random_forest_regressor.py +5 -4
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +7 -7
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +4 -4
- {aiq → nat}/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +6 -6
- {aiq → nat}/profiler/inference_optimization/experimental/prefix_span_analysis.py +6 -6
- {aiq → nat}/profiler/inference_optimization/llm_metrics.py +2 -2
- {aiq → nat}/profiler/inference_optimization/prompt_caching.py +5 -5
- {aiq → nat}/profiler/inference_optimization/token_uniqueness.py +4 -4
- {aiq → nat}/profiler/inference_optimization/workflow_runtimes.py +3 -3
- {aiq → nat}/profiler/intermediate_property_adapter.py +3 -3
- {aiq → nat}/profiler/profile_runner.py +17 -17
- {aiq → nat}/profiler/utils.py +4 -4
- {aiq → nat}/registry_handlers/local/local_handler.py +19 -19
- {aiq → nat}/registry_handlers/local/register_local.py +4 -4
- {aiq → nat}/registry_handlers/metadata_factory.py +7 -7
- {aiq → nat}/registry_handlers/package_utils.py +37 -33
- {aiq → nat}/registry_handlers/pypi/pypi_handler.py +21 -21
- {aiq → nat}/registry_handlers/pypi/register_pypi.py +6 -6
- {aiq → nat}/registry_handlers/registry_handler_base.py +21 -21
- {aiq → nat}/registry_handlers/rest/register_rest.py +7 -7
- {aiq → nat}/registry_handlers/rest/rest_handler.py +19 -19
- {aiq → nat}/registry_handlers/schemas/package.py +3 -3
- {aiq → nat}/registry_handlers/schemas/publish.py +17 -12
- {aiq → nat}/registry_handlers/schemas/pull.py +6 -6
- {aiq → nat}/registry_handlers/schemas/remove.py +2 -2
- {aiq → nat}/registry_handlers/schemas/search.py +11 -11
- {aiq → nat}/retriever/interface.py +6 -2
- {aiq → nat}/retriever/milvus/register.py +7 -7
- {aiq → nat}/retriever/milvus/retriever.py +8 -8
- {aiq → nat}/retriever/models.py +10 -7
- {aiq → nat}/retriever/nemo_retriever/register.py +6 -6
- {aiq → nat}/retriever/nemo_retriever/retriever.py +10 -10
- {aiq/embedder → nat/retriever}/register.py +2 -4
- {aiq → nat}/runtime/loader.py +38 -33
- {aiq → nat}/runtime/runner.py +30 -25
- {aiq → nat}/runtime/session.py +19 -15
- {aiq → nat}/runtime/user_metadata.py +1 -1
- {aiq → nat}/settings/global_settings.py +11 -11
- {aiq → nat}/tool/chat_completion.py +6 -6
- {aiq → nat}/tool/code_execution/README.md +2 -2
- {aiq → nat}/tool/code_execution/code_sandbox.py +1 -1
- {aiq → nat}/tool/code_execution/register.py +5 -5
- {aiq → nat}/tool/code_execution/test_code_execution_sandbox.py +1 -1
- {aiq → nat}/tool/datetime_tools.py +4 -4
- {aiq → nat}/tool/document_search.py +6 -6
- {aiq → nat}/tool/github_tools/create_github_commit.py +4 -4
- {aiq → nat}/tool/github_tools/create_github_issue.py +4 -4
- {aiq → nat}/tool/github_tools/create_github_pr.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_file.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_issue.py +4 -4
- {aiq → nat}/tool/github_tools/get_github_pr.py +4 -4
- {aiq → nat}/tool/github_tools/update_github_issue.py +4 -4
- {aiq → nat}/tool/mcp/exceptions.py +1 -1
- {aiq → nat}/tool/mcp/mcp_client.py +2 -2
- {aiq → nat}/tool/mcp/mcp_tool.py +7 -7
- {aiq → nat}/tool/memory_tools/add_memory_tool.py +6 -6
- {aiq → nat}/tool/memory_tools/delete_memory_tool.py +6 -6
- {aiq → nat}/tool/memory_tools/get_memory_tool.py +6 -6
- {aiq → nat}/tool/nvidia_rag.py +4 -4
- {aiq → nat}/tool/retriever.py +20 -15
- {aiq → nat}/tool/server_tools.py +16 -16
- {aiq → nat}/utils/dump_distro_mapping.py +2 -2
- {aiq → nat}/utils/exception_handlers/mcp.py +8 -8
- {aiq → nat}/utils/io/yaml_tools.py +1 -1
- {aiq → nat}/utils/metadata_utils.py +2 -2
- {aiq → nat}/utils/reactive/base/observable_base.py +2 -2
- {aiq → nat}/utils/reactive/base/subject_base.py +1 -1
- {aiq → nat}/utils/reactive/observable.py +5 -5
- {aiq → nat}/utils/reactive/observer.py +1 -1
- {aiq → nat}/utils/reactive/subject.py +4 -4
- {aiq → nat}/utils/reactive/subscription.py +1 -1
- {aiq → nat}/utils/settings/global_settings.py +4 -4
- {aiq → nat}/utils/type_converter.py +1 -1
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc7.dist-info}/METADATA +37 -37
- nvidia_nat-1.2.0rc7.dist-info/RECORD +434 -0
- nvidia_nat-1.2.0rc7.dist-info/entry_points.txt +21 -0
- nvidia_nat-1.2.0rc7.dist-info/top_level.txt +1 -0
- aiq/embedder/langchain_client.py +0 -41
- aiq/front_ends/mcp/mcp_front_end_plugin.py +0 -93
- aiq/meta/module_to_distro.json +0 -3
- aiq/meta/pypi.md +0 -58
- nvidia_nat-1.2.0rc5.dist-info/RECORD +0 -435
- nvidia_nat-1.2.0rc5.dist-info/entry_points.txt +0 -20
- nvidia_nat-1.2.0rc5.dist-info/top_level.txt +0 -1
- {aiq → nat}/agent/__init__.py +0 -0
- {aiq → nat}/agent/base.py +0 -0
- {aiq → nat}/agent/dual_node.py +0 -0
- {aiq → nat}/agent/react_agent/__init__.py +0 -0
- {aiq → nat}/agent/react_agent/output_parser.py +0 -0
- {aiq → nat}/agent/react_agent/prompt.py +0 -0
- {aiq → nat}/agent/reasoning_agent/__init__.py +0 -0
- {aiq → nat}/agent/register.py +0 -0
- {aiq → nat}/agent/rewoo_agent/__init__.py +0 -0
- {aiq → nat}/agent/tool_calling_agent/__init__.py +0 -0
- {aiq → nat}/authentication/__init__.py +0 -0
- {aiq → nat}/authentication/api_key/__init__.py +0 -0
- {aiq → nat}/authentication/exceptions/__init__.py +0 -0
- {aiq → nat}/authentication/exceptions/api_key_exceptions.py +0 -0
- {aiq → nat}/authentication/http_basic_auth/__init__.py +0 -0
- {aiq → nat}/authentication/oauth2/__init__.py +0 -0
- {aiq → nat}/builder/__init__.py +0 -0
- {aiq → nat}/builder/framework_enum.py +0 -0
- {aiq → nat}/cli/__init__.py +0 -0
- {aiq → nat}/cli/cli_utils/__init__.py +0 -0
- {aiq → nat}/cli/commands/__init__.py +0 -0
- {aiq → nat}/cli/commands/configure/__init__.py +0 -0
- {aiq → nat}/cli/commands/configure/channel/__init__.py +0 -0
- {aiq → nat}/cli/commands/info/__init__.py +0 -0
- {aiq → nat}/cli/commands/registry/__init__.py +0 -0
- {aiq → nat}/cli/commands/sizing/__init__.py +0 -0
- {aiq → nat}/cli/commands/sizing/sizing.py +0 -0
- {aiq → nat}/cli/commands/workflow/__init__.py +0 -0
- {aiq → nat}/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- {aiq → nat}/cli/commands/workflow/templates/config.yml.j2 +0 -0
- {aiq → nat}/cli/commands/workflow/templates/register.py.j2 +0 -0
- {aiq → nat}/data_models/__init__.py +0 -0
- {aiq → nat}/data_models/common.py +0 -0
- {aiq → nat}/data_models/embedder.py +0 -0
- {aiq → nat}/data_models/evaluator.py +0 -0
- {aiq → nat}/data_models/front_end.py +0 -0
- {aiq → nat}/data_models/function.py +0 -0
- {aiq → nat}/data_models/function_dependencies.py +0 -0
- {aiq → nat}/data_models/interactive.py +0 -0
- {aiq → nat}/data_models/invocation_node.py +0 -0
- {aiq → nat}/data_models/llm.py +0 -0
- {aiq → nat}/data_models/logging.py +0 -0
- {aiq → nat}/data_models/memory.py +0 -0
- {aiq → nat}/data_models/object_store.py +0 -0
- {aiq → nat}/data_models/profiler.py +0 -0
- {aiq → nat}/data_models/registry_handler.py +0 -0
- {aiq → nat}/data_models/retry_mixin.py +0 -0
- {aiq → nat}/data_models/streaming.py +0 -0
- {aiq → nat}/data_models/swe_bench_model.py +0 -0
- {aiq → nat}/data_models/ttc_strategy.py +0 -0
- {aiq → nat}/embedder/__init__.py +0 -0
- {aiq → nat}/eval/__init__.py +0 -0
- {aiq → nat}/eval/dataset_handler/__init__.py +0 -0
- {aiq → nat}/eval/evaluator/__init__.py +0 -0
- {aiq → nat}/eval/rag_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/register.py +0 -0
- {aiq → nat}/eval/runners/__init__.py +0 -0
- {aiq → nat}/eval/swe_bench_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/trajectory_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/tunable_rag_evaluator/__init__.py +0 -0
- {aiq → nat}/eval/usage_stats.py +0 -0
- {aiq → nat}/eval/utils/__init__.py +0 -0
- {aiq → nat}/eval/utils/tqdm_position_registry.py +0 -0
- {aiq → nat}/experimental/__init__.py +0 -0
- {aiq → nat}/experimental/decorators/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/editing/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/functions/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/stage_enums.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/tool_use_config.py +0 -0
- {aiq → nat}/experimental/test_time_compute/models/ttc_item.py +0 -0
- {aiq → nat}/experimental/test_time_compute/scoring/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/search/__init__.py +0 -0
- {aiq → nat}/experimental/test_time_compute/selection/__init__.py +0 -0
- {aiq → nat}/front_ends/__init__.py +0 -0
- {aiq → nat}/front_ends/console/__init__.py +0 -0
- {aiq → nat}/front_ends/cron/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/fastapi_front_end_controller.py +0 -0
- {aiq → nat}/front_ends/fastapi/html_snippets/__init__.py +0 -0
- {aiq → nat}/front_ends/fastapi/html_snippets/auth_code_grant_success.py +0 -0
- {aiq → nat}/front_ends/fastapi/job_store.py +0 -0
- {aiq → nat}/front_ends/mcp/__init__.py +0 -0
- {aiq → nat}/front_ends/register.py +0 -0
- {aiq → nat}/front_ends/simple_base/__init__.py +0 -0
- {aiq → nat}/llm/__init__.py +0 -0
- {aiq → nat}/llm/register.py +0 -0
- {aiq → nat}/llm/utils/__init__.py +0 -0
- {aiq → nat}/llm/utils/env_config_value.py +0 -0
- {aiq → nat}/llm/utils/error.py +0 -0
- {aiq → nat}/memory/interfaces.py +0 -0
- {aiq → nat}/memory/models.py +0 -0
- {aiq → nat}/object_store/interfaces.py +0 -0
- {aiq → nat}/object_store/models.py +0 -0
- {aiq → nat}/object_store/register.py +0 -0
- {aiq → nat}/observability/__init__.py +0 -0
- {aiq → nat}/observability/exporter/__init__.py +0 -0
- {aiq → nat}/observability/mixin/__init__.py +0 -0
- {aiq → nat}/observability/mixin/batch_config_mixin.py +0 -0
- {aiq → nat}/observability/mixin/collector_config_mixin.py +0 -0
- {aiq → nat}/observability/mixin/file_mode.py +0 -0
- {aiq → nat}/observability/mixin/resource_conflict_mixin.py +0 -0
- {aiq → nat}/observability/mixin/serialize_mixin.py +0 -0
- {aiq → nat}/observability/mixin/type_introspection_mixin.py +0 -0
- {aiq → nat}/observability/processor/__init__.py +0 -0
- {aiq → nat}/observability/utils/__init__.py +0 -0
- {aiq → nat}/observability/utils/dict_utils.py +0 -0
- {aiq → nat}/observability/utils/time_utils.py +0 -0
- {aiq → nat}/plugins/.namespace +0 -0
- {aiq → nat}/profiler/__init__.py +0 -0
- {aiq → nat}/profiler/calc/__init__.py +0 -0
- {aiq → nat}/profiler/calc/data_models.py +0 -0
- {aiq → nat}/profiler/callbacks/__init__.py +0 -0
- {aiq → nat}/profiler/callbacks/base_callback_class.py +0 -0
- {aiq → nat}/profiler/callbacks/token_usage_base_model.py +0 -0
- {aiq → nat}/profiler/data_frame_row.py +0 -0
- {aiq → nat}/profiler/decorators/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/config.py +0 -0
- {aiq → nat}/profiler/forecasting/models/__init__.py +0 -0
- {aiq → nat}/profiler/forecasting/models/forecasting_base_model.py +0 -0
- {aiq → nat}/profiler/inference_metrics_model.py +0 -0
- {aiq → nat}/profiler/inference_optimization/__init__.py +0 -0
- {aiq → nat}/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- {aiq → nat}/profiler/inference_optimization/data_models.py +0 -0
- {aiq → nat}/profiler/inference_optimization/experimental/__init__.py +0 -0
- {aiq → nat}/registry_handlers/__init__.py +0 -0
- {aiq → nat}/registry_handlers/local/__init__.py +0 -0
- {aiq → nat}/registry_handlers/pypi/__init__.py +0 -0
- {aiq → nat}/registry_handlers/register.py +0 -0
- {aiq → nat}/registry_handlers/rest/__init__.py +0 -0
- {aiq → nat}/registry_handlers/schemas/__init__.py +0 -0
- {aiq → nat}/registry_handlers/schemas/headers.py +0 -0
- {aiq → nat}/registry_handlers/schemas/status.py +0 -0
- {aiq → nat}/retriever/__init__.py +0 -0
- {aiq → nat}/retriever/milvus/__init__.py +0 -0
- {aiq → nat}/retriever/nemo_retriever/__init__.py +0 -0
- {aiq → nat}/runtime/__init__.py +0 -0
- {aiq → nat}/settings/__init__.py +0 -0
- {aiq → nat}/test/.namespace +0 -0
- {aiq → nat}/tool/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/.gitignore +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/Dockerfile.sandbox +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/__init__.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/local_sandbox_server.py +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/sandbox.requirements.txt +0 -0
- {aiq → nat}/tool/code_execution/local_sandbox/start_local_sandbox.sh +0 -0
- {aiq → nat}/tool/code_execution/utils.py +0 -0
- {aiq → nat}/tool/github_tools/__init__.py +0 -0
- {aiq → nat}/tool/mcp/__init__.py +0 -0
- {aiq → nat}/tool/memory_tools/__init__.py +0 -0
- {aiq → nat}/tool/register.py +0 -0
- {aiq → nat}/utils/__init__.py +0 -0
- {aiq → nat}/utils/data_models/__init__.py +0 -0
- {aiq → nat}/utils/data_models/schema_validator.py +0 -0
- {aiq → nat}/utils/debugging_utils.py +0 -0
- {aiq → nat}/utils/exception_handlers/__init__.py +0 -0
- {aiq → nat}/utils/exception_handlers/automatic_retries.py +0 -0
- {aiq → nat}/utils/exception_handlers/schemas.py +0 -0
- {aiq → nat}/utils/io/__init__.py +0 -0
- {aiq → nat}/utils/io/model_processing.py +0 -0
- {aiq → nat}/utils/log_utils.py +0 -0
- {aiq → nat}/utils/optional_imports.py +0 -0
- {aiq → nat}/utils/producer_consumer_queue.py +0 -0
- {aiq → nat}/utils/reactive/__init__.py +0 -0
- {aiq → nat}/utils/reactive/base/__init__.py +0 -0
- {aiq → nat}/utils/reactive/base/observer_base.py +0 -0
- {aiq → nat}/utils/settings/__init__.py +0 -0
- {aiq → nat}/utils/string_utils.py +0 -0
- {aiq → nat}/utils/type_utils.py +0 -0
- {aiq → nat}/utils/url_utils.py +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc7.dist-info}/WHEEL +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc7.dist-info}/licenses/LICENSE-3rd-party.txt +0 -0
- {nvidia_nat-1.2.0rc5.dist-info → nvidia_nat-1.2.0rc7.dist-info}/licenses/LICENSE.md +0 -0
|
@@ -38,42 +38,42 @@ from pydantic import BaseModel
|
|
|
38
38
|
from pydantic import Field
|
|
39
39
|
from starlette.websockets import WebSocket
|
|
40
40
|
|
|
41
|
-
from
|
|
42
|
-
from
|
|
43
|
-
from
|
|
44
|
-
from
|
|
45
|
-
from
|
|
46
|
-
from
|
|
47
|
-
from
|
|
48
|
-
from
|
|
49
|
-
from
|
|
50
|
-
from
|
|
51
|
-
from
|
|
52
|
-
from
|
|
53
|
-
from
|
|
54
|
-
from
|
|
55
|
-
from
|
|
56
|
-
from
|
|
57
|
-
from
|
|
58
|
-
from
|
|
59
|
-
from
|
|
60
|
-
from
|
|
61
|
-
from
|
|
62
|
-
from
|
|
63
|
-
from
|
|
64
|
-
from
|
|
65
|
-
from
|
|
66
|
-
from
|
|
67
|
-
from
|
|
68
|
-
from
|
|
69
|
-
from
|
|
41
|
+
from nat.builder.workflow_builder import WorkflowBuilder
|
|
42
|
+
from nat.data_models.api_server import ChatRequest
|
|
43
|
+
from nat.data_models.api_server import ChatResponse
|
|
44
|
+
from nat.data_models.api_server import ChatResponseChunk
|
|
45
|
+
from nat.data_models.api_server import ResponseIntermediateStep
|
|
46
|
+
from nat.data_models.config import Config
|
|
47
|
+
from nat.data_models.object_store import KeyAlreadyExistsError
|
|
48
|
+
from nat.data_models.object_store import NoSuchKeyError
|
|
49
|
+
from nat.eval.config import EvaluationRunOutput
|
|
50
|
+
from nat.eval.evaluate import EvaluationRun
|
|
51
|
+
from nat.eval.evaluate import EvaluationRunConfig
|
|
52
|
+
from nat.front_ends.fastapi.auth_flow_handlers.http_flow_handler import HTTPAuthenticationFlowHandler
|
|
53
|
+
from nat.front_ends.fastapi.auth_flow_handlers.websocket_flow_handler import FlowState
|
|
54
|
+
from nat.front_ends.fastapi.auth_flow_handlers.websocket_flow_handler import WebSocketAuthenticationFlowHandler
|
|
55
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import AsyncGenerateResponse
|
|
56
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import AsyncGenerationStatusResponse
|
|
57
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import EvaluateRequest
|
|
58
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import EvaluateResponse
|
|
59
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import EvaluateStatusResponse
|
|
60
|
+
from nat.front_ends.fastapi.fastapi_front_end_config import FastApiFrontEndConfig
|
|
61
|
+
from nat.front_ends.fastapi.job_store import JobInfo
|
|
62
|
+
from nat.front_ends.fastapi.job_store import JobStore
|
|
63
|
+
from nat.front_ends.fastapi.message_handler import WebSocketMessageHandler
|
|
64
|
+
from nat.front_ends.fastapi.response_helpers import generate_single_response
|
|
65
|
+
from nat.front_ends.fastapi.response_helpers import generate_streaming_response_as_str
|
|
66
|
+
from nat.front_ends.fastapi.response_helpers import generate_streaming_response_full_as_str
|
|
67
|
+
from nat.front_ends.fastapi.step_adaptor import StepAdaptor
|
|
68
|
+
from nat.object_store.models import ObjectStoreItem
|
|
69
|
+
from nat.runtime.session import SessionManager
|
|
70
70
|
|
|
71
71
|
logger = logging.getLogger(__name__)
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
class FastApiFrontEndPluginWorkerBase(ABC):
|
|
75
75
|
|
|
76
|
-
def __init__(self, config:
|
|
76
|
+
def __init__(self, config: Config):
|
|
77
77
|
self._config = config
|
|
78
78
|
|
|
79
79
|
assert isinstance(config.general.front_end,
|
|
@@ -86,7 +86,7 @@ class FastApiFrontEndPluginWorkerBase(ABC):
|
|
|
86
86
|
self._http_flow_handler: HTTPAuthenticationFlowHandler | None = HTTPAuthenticationFlowHandler()
|
|
87
87
|
|
|
88
88
|
@property
|
|
89
|
-
def config(self) ->
|
|
89
|
+
def config(self) -> Config:
|
|
90
90
|
return self._config
|
|
91
91
|
|
|
92
92
|
@property
|
|
@@ -99,7 +99,7 @@ class FastApiFrontEndPluginWorkerBase(ABC):
|
|
|
99
99
|
@asynccontextmanager
|
|
100
100
|
async def lifespan(starting_app: FastAPI):
|
|
101
101
|
|
|
102
|
-
logger.debug("Starting
|
|
102
|
+
logger.debug("Starting NAT server from process %s", os.getpid())
|
|
103
103
|
|
|
104
104
|
async with WorkflowBuilder.from_config(self.config) as builder:
|
|
105
105
|
|
|
@@ -121,20 +121,20 @@ class FastApiFrontEndPluginWorkerBase(ABC):
|
|
|
121
121
|
|
|
122
122
|
self._cleanup_tasks.clear()
|
|
123
123
|
|
|
124
|
-
logger.debug("Closing
|
|
124
|
+
logger.debug("Closing NAT server from process %s", os.getpid())
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
nat_app = FastAPI(lifespan=lifespan)
|
|
127
127
|
|
|
128
128
|
# Configure app CORS.
|
|
129
|
-
self.set_cors_config(
|
|
129
|
+
self.set_cors_config(nat_app)
|
|
130
130
|
|
|
131
|
-
@
|
|
131
|
+
@nat_app.middleware("http")
|
|
132
132
|
async def authentication_log_filter(request: Request, call_next: Callable[[Request], Awaitable[Response]]):
|
|
133
133
|
return await self._suppress_authentication_logs(request, call_next)
|
|
134
134
|
|
|
135
|
-
return
|
|
135
|
+
return nat_app
|
|
136
136
|
|
|
137
|
-
def set_cors_config(self,
|
|
137
|
+
def set_cors_config(self, nat_app: FastAPI) -> None:
|
|
138
138
|
"""
|
|
139
139
|
Set the cross origin resource sharing configuration.
|
|
140
140
|
"""
|
|
@@ -161,7 +161,7 @@ class FastApiFrontEndPluginWorkerBase(ABC):
|
|
|
161
161
|
if self.front_end_config.cors.max_age is not None:
|
|
162
162
|
cors_kwargs["max_age"] = self.front_end_config.cors.max_age
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
nat_app.add_middleware(
|
|
165
165
|
CORSMiddleware,
|
|
166
166
|
**cors_kwargs,
|
|
167
167
|
)
|
|
@@ -171,7 +171,7 @@ class FastApiFrontEndPluginWorkerBase(ABC):
|
|
|
171
171
|
"""
|
|
172
172
|
Intercepts authentication request and supreses logs that contain sensitive data.
|
|
173
173
|
"""
|
|
174
|
-
from
|
|
174
|
+
from nat.utils.log_utils import LogFilter
|
|
175
175
|
|
|
176
176
|
logs_to_suppress: list[str] = []
|
|
177
177
|
|
|
@@ -202,7 +202,7 @@ class RouteInfo(BaseModel):
|
|
|
202
202
|
|
|
203
203
|
class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
204
204
|
|
|
205
|
-
def __init__(self, config:
|
|
205
|
+
def __init__(self, config: Config):
|
|
206
206
|
super().__init__(config)
|
|
207
207
|
|
|
208
208
|
self._outstanding_flows: dict[str, FlowState] = {}
|
|
@@ -247,8 +247,8 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
247
247
|
|
|
248
248
|
async def add_routes(self, app: FastAPI, builder: WorkflowBuilder):
|
|
249
249
|
|
|
250
|
-
await self.add_default_route(app,
|
|
251
|
-
await self.add_evaluate_route(app,
|
|
250
|
+
await self.add_default_route(app, SessionManager(builder.build()))
|
|
251
|
+
await self.add_evaluate_route(app, SessionManager(builder.build()))
|
|
252
252
|
await self.add_static_files_route(app, builder)
|
|
253
253
|
await self.add_authorization_route(app)
|
|
254
254
|
|
|
@@ -256,13 +256,13 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
256
256
|
|
|
257
257
|
entry_workflow = builder.build(entry_function=ep.function_name)
|
|
258
258
|
|
|
259
|
-
await self.add_route(app, endpoint=ep, session_manager=
|
|
259
|
+
await self.add_route(app, endpoint=ep, session_manager=SessionManager(entry_workflow))
|
|
260
260
|
|
|
261
|
-
async def add_default_route(self, app: FastAPI, session_manager:
|
|
261
|
+
async def add_default_route(self, app: FastAPI, session_manager: SessionManager):
|
|
262
262
|
|
|
263
263
|
await self.add_route(app, self.front_end_config.workflow, session_manager)
|
|
264
264
|
|
|
265
|
-
async def add_evaluate_route(self, app: FastAPI, session_manager:
|
|
265
|
+
async def add_evaluate_route(self, app: FastAPI, session_manager: SessionManager):
|
|
266
266
|
"""Add the evaluate endpoint to the FastAPI app."""
|
|
267
267
|
|
|
268
268
|
response_500 = {
|
|
@@ -281,7 +281,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
281
281
|
# Don't run multiple evaluations at the same time
|
|
282
282
|
evaluation_lock = asyncio.Lock()
|
|
283
283
|
|
|
284
|
-
async def run_evaluation(job_id: str, config_file: str, reps: int, session_manager:
|
|
284
|
+
async def run_evaluation(job_id: str, config_file: str, reps: int, session_manager: SessionManager):
|
|
285
285
|
"""Background task to run the evaluation."""
|
|
286
286
|
async with evaluation_lock:
|
|
287
287
|
try:
|
|
@@ -304,9 +304,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
304
304
|
logger.error("Error in evaluation job %s: %s", job_id, str(e))
|
|
305
305
|
job_store.update_status(job_id, "failure", error=str(e))
|
|
306
306
|
|
|
307
|
-
async def start_evaluation(request:
|
|
308
|
-
background_tasks: BackgroundTasks,
|
|
309
|
-
http_request: Request):
|
|
307
|
+
async def start_evaluation(request: EvaluateRequest, background_tasks: BackgroundTasks, http_request: Request):
|
|
310
308
|
"""Handle evaluation requests."""
|
|
311
309
|
|
|
312
310
|
async with session_manager.session(request=http_request):
|
|
@@ -315,26 +313,26 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
315
313
|
if request.job_id:
|
|
316
314
|
job = job_store.get_job(request.job_id)
|
|
317
315
|
if job:
|
|
318
|
-
return
|
|
316
|
+
return EvaluateResponse(job_id=job.job_id, status=job.status)
|
|
319
317
|
|
|
320
318
|
job_id = job_store.create_job(request.config_file, request.job_id, request.expiry_seconds)
|
|
321
319
|
await self.create_cleanup_task(app=app, name="async_evaluation", job_store=job_store)
|
|
322
320
|
background_tasks.add_task(run_evaluation, job_id, request.config_file, request.reps, session_manager)
|
|
323
321
|
|
|
324
|
-
return
|
|
322
|
+
return EvaluateResponse(job_id=job_id, status="submitted")
|
|
325
323
|
|
|
326
|
-
def translate_job_to_response(job: JobInfo) ->
|
|
327
|
-
"""Translate a JobInfo object to an
|
|
328
|
-
return
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
324
|
+
def translate_job_to_response(job: JobInfo) -> EvaluateStatusResponse:
|
|
325
|
+
"""Translate a JobInfo object to an EvaluateStatusResponse."""
|
|
326
|
+
return EvaluateStatusResponse(job_id=job.job_id,
|
|
327
|
+
status=job.status,
|
|
328
|
+
config_file=str(job.config_file),
|
|
329
|
+
error=job.error,
|
|
330
|
+
output_path=str(job.output_path),
|
|
331
|
+
created_at=job.created_at,
|
|
332
|
+
updated_at=job.updated_at,
|
|
333
|
+
expires_at=job_store.get_expires_at(job))
|
|
336
334
|
|
|
337
|
-
async def get_job_status(job_id: str, http_request: Request) ->
|
|
335
|
+
async def get_job_status(job_id: str, http_request: Request) -> EvaluateStatusResponse:
|
|
338
336
|
"""Get the status of an evaluation job."""
|
|
339
337
|
logger.info("Getting status for job %s", job_id)
|
|
340
338
|
|
|
@@ -347,7 +345,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
347
345
|
logger.info("Found job %s with status %s", job_id, job.status)
|
|
348
346
|
return translate_job_to_response(job)
|
|
349
347
|
|
|
350
|
-
async def get_last_job_status(http_request: Request) ->
|
|
348
|
+
async def get_last_job_status(http_request: Request) -> EvaluateStatusResponse:
|
|
351
349
|
"""Get the status of the last created evaluation job."""
|
|
352
350
|
logger.info("Getting last job status")
|
|
353
351
|
|
|
@@ -360,7 +358,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
360
358
|
logger.info("Found last job %s with status %s", job.job_id, job.status)
|
|
361
359
|
return translate_job_to_response(job)
|
|
362
360
|
|
|
363
|
-
async def get_jobs(http_request: Request, status: str | None = None) -> list[
|
|
361
|
+
async def get_jobs(http_request: Request, status: str | None = None) -> list[EvaluateStatusResponse]:
|
|
364
362
|
"""Get all jobs, optionally filtered by status."""
|
|
365
363
|
|
|
366
364
|
async with session_manager.session(request=http_request):
|
|
@@ -380,7 +378,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
380
378
|
path=f"{self.front_end_config.evaluate.path}/job/last",
|
|
381
379
|
endpoint=get_last_job_status,
|
|
382
380
|
methods=["GET"],
|
|
383
|
-
response_model=
|
|
381
|
+
response_model=EvaluateStatusResponse,
|
|
384
382
|
description="Get the status of the last created evaluation job",
|
|
385
383
|
responses={
|
|
386
384
|
404: {
|
|
@@ -394,7 +392,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
394
392
|
path=f"{self.front_end_config.evaluate.path}/job/{{job_id}}",
|
|
395
393
|
endpoint=get_job_status,
|
|
396
394
|
methods=["GET"],
|
|
397
|
-
response_model=
|
|
395
|
+
response_model=EvaluateStatusResponse,
|
|
398
396
|
description="Get the status of an evaluation job",
|
|
399
397
|
responses={
|
|
400
398
|
404: {
|
|
@@ -408,7 +406,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
408
406
|
path=f"{self.front_end_config.evaluate.path}/jobs",
|
|
409
407
|
endpoint=get_jobs,
|
|
410
408
|
methods=["GET"],
|
|
411
|
-
response_model=list[
|
|
409
|
+
response_model=list[EvaluateStatusResponse],
|
|
412
410
|
description="Get all jobs, optionally filtered by status",
|
|
413
411
|
responses={500: response_500},
|
|
414
412
|
)
|
|
@@ -418,7 +416,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
418
416
|
path=self.front_end_config.evaluate.path,
|
|
419
417
|
endpoint=start_evaluation,
|
|
420
418
|
methods=[self.front_end_config.evaluate.method],
|
|
421
|
-
response_model=
|
|
419
|
+
response_model=EvaluateResponse,
|
|
422
420
|
description=self.front_end_config.evaluate.description,
|
|
423
421
|
responses={500: response_500},
|
|
424
422
|
)
|
|
@@ -520,7 +518,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
520
518
|
async def add_route(self,
|
|
521
519
|
app: FastAPI,
|
|
522
520
|
endpoint: FastApiFrontEndConfig.EndpointBase,
|
|
523
|
-
session_manager:
|
|
521
|
+
session_manager: SessionManager):
|
|
524
522
|
|
|
525
523
|
workflow = session_manager.workflow
|
|
526
524
|
|
|
@@ -529,8 +527,8 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
529
527
|
GenerateSingleResponseType = workflow.single_output_schema # pylint: disable=invalid-name
|
|
530
528
|
|
|
531
529
|
# Append job_id and expiry_seconds to the input schema, this effectively makes these reserved keywords
|
|
532
|
-
# Consider prefixing these with "
|
|
533
|
-
class
|
|
530
|
+
# Consider prefixing these with "nat_" to avoid conflicts
|
|
531
|
+
class AsyncGenerateRequest(GenerateBodyType):
|
|
534
532
|
job_id: str | None = Field(default=None, description="Unique identifier for the evaluation job")
|
|
535
533
|
sync_timeout: int = Field(
|
|
536
534
|
default=0,
|
|
@@ -688,13 +686,13 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
688
686
|
session_manager=session_manager,
|
|
689
687
|
streaming=True,
|
|
690
688
|
step_adaptor=self.get_step_adaptor(),
|
|
691
|
-
result_type=
|
|
692
|
-
output_type=
|
|
689
|
+
result_type=ChatResponseChunk,
|
|
690
|
+
output_type=ChatResponseChunk))
|
|
693
691
|
else:
|
|
694
692
|
# Return single response - check if workflow supports non-streaming
|
|
695
693
|
try:
|
|
696
694
|
response.headers["Content-Type"] = "application/json"
|
|
697
|
-
return await generate_single_response(payload, session_manager, result_type=
|
|
695
|
+
return await generate_single_response(payload, session_manager, result_type=ChatResponse)
|
|
698
696
|
except ValueError as e:
|
|
699
697
|
if "Cannot get a single output value for streaming workflows" in str(e):
|
|
700
698
|
# Workflow only supports streaming, but client requested non-streaming
|
|
@@ -705,13 +703,13 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
705
703
|
session_manager=session_manager,
|
|
706
704
|
streaming=True,
|
|
707
705
|
step_adaptor=self.get_step_adaptor(),
|
|
708
|
-
result_type=
|
|
709
|
-
output_type=
|
|
706
|
+
result_type=ChatResponseChunk,
|
|
707
|
+
output_type=ChatResponseChunk):
|
|
710
708
|
if chunk_str.startswith("data: ") and not chunk_str.startswith("data: [DONE]"):
|
|
711
709
|
chunk_data = chunk_str[6:].strip() # Remove "data: " prefix
|
|
712
710
|
if chunk_data:
|
|
713
711
|
try:
|
|
714
|
-
chunk_json =
|
|
712
|
+
chunk_json = ChatResponseChunk.model_validate_json(chunk_data)
|
|
715
713
|
if (chunk_json.choices and len(chunk_json.choices) > 0
|
|
716
714
|
and chunk_json.choices[0].delta
|
|
717
715
|
and chunk_json.choices[0].delta.content is not None):
|
|
@@ -721,7 +719,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
721
719
|
|
|
722
720
|
# Create a single response from collected chunks
|
|
723
721
|
content = "".join(chunks)
|
|
724
|
-
single_response =
|
|
722
|
+
single_response = ChatResponse.from_string(content)
|
|
725
723
|
response.headers["Content-Type"] = "application/json"
|
|
726
724
|
return single_response
|
|
727
725
|
else:
|
|
@@ -729,10 +727,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
729
727
|
|
|
730
728
|
return post_openai_api_compatible
|
|
731
729
|
|
|
732
|
-
async def run_generation(job_id: str,
|
|
733
|
-
payload: typing.Any,
|
|
734
|
-
session_manager: AIQSessionManager,
|
|
735
|
-
result_type: type):
|
|
730
|
+
async def run_generation(job_id: str, payload: typing.Any, session_manager: SessionManager, result_type: type):
|
|
736
731
|
"""Background task to run the evaluation."""
|
|
737
732
|
async with async_job_concurrency:
|
|
738
733
|
try:
|
|
@@ -744,23 +739,23 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
744
739
|
logger.error("Error in evaluation job %s: %s", job_id, e)
|
|
745
740
|
job_store.update_status(job_id, "failure", error=str(e))
|
|
746
741
|
|
|
747
|
-
def _job_status_to_response(job: JobInfo) ->
|
|
742
|
+
def _job_status_to_response(job: JobInfo) -> AsyncGenerationStatusResponse:
|
|
748
743
|
job_output = job.output
|
|
749
744
|
if job_output is not None:
|
|
750
745
|
job_output = job_output.model_dump()
|
|
751
|
-
return
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
746
|
+
return AsyncGenerationStatusResponse(job_id=job.job_id,
|
|
747
|
+
status=job.status,
|
|
748
|
+
error=job.error,
|
|
749
|
+
output=job_output,
|
|
750
|
+
created_at=job.created_at,
|
|
751
|
+
updated_at=job.updated_at,
|
|
752
|
+
expires_at=job_store.get_expires_at(job))
|
|
758
753
|
|
|
759
754
|
def post_async_generation(request_type: type, final_result_type: type):
|
|
760
755
|
|
|
761
756
|
async def start_async_generation(
|
|
762
757
|
request: request_type, background_tasks: BackgroundTasks, response: Response,
|
|
763
|
-
http_request: Request) ->
|
|
758
|
+
http_request: Request) -> AsyncGenerateResponse | AsyncGenerationStatusResponse:
|
|
764
759
|
"""Handle async generation requests."""
|
|
765
760
|
|
|
766
761
|
async with session_manager.session(request=http_request):
|
|
@@ -769,7 +764,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
769
764
|
if request.job_id:
|
|
770
765
|
job = job_store.get_job(request.job_id)
|
|
771
766
|
if job:
|
|
772
|
-
return
|
|
767
|
+
return AsyncGenerateResponse(job_id=job.job_id, status=job.status)
|
|
773
768
|
|
|
774
769
|
job_id = job_store.create_job(job_id=request.job_id, expiry_seconds=request.expiry_seconds)
|
|
775
770
|
await self.create_cleanup_task(app=app, name="async_generation", job_store=job_store)
|
|
@@ -801,11 +796,11 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
801
796
|
await asyncio.sleep(0.1)
|
|
802
797
|
|
|
803
798
|
response.status_code = 202
|
|
804
|
-
return
|
|
799
|
+
return AsyncGenerateResponse(job_id=job_id, status="submitted")
|
|
805
800
|
|
|
806
801
|
return start_async_generation
|
|
807
802
|
|
|
808
|
-
async def get_async_job_status(job_id: str, http_request: Request) ->
|
|
803
|
+
async def get_async_job_status(job_id: str, http_request: Request) -> AsyncGenerationStatusResponse:
|
|
809
804
|
"""Get the status of an async job."""
|
|
810
805
|
logger.info("Getting status for job %s", job_id)
|
|
811
806
|
|
|
@@ -825,7 +820,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
825
820
|
session_id = websocket.query_params.get("session")
|
|
826
821
|
if session_id:
|
|
827
822
|
headers = list(websocket.scope.get("headers", []))
|
|
828
|
-
cookie_header = f"
|
|
823
|
+
cookie_header = f"nat-session={session_id}"
|
|
829
824
|
|
|
830
825
|
# Check if the session cookie already exists to avoid duplicates
|
|
831
826
|
cookie_exists = False
|
|
@@ -836,8 +831,8 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
836
831
|
cookie_exists = True
|
|
837
832
|
cookie_str = value.decode()
|
|
838
833
|
|
|
839
|
-
# Check if
|
|
840
|
-
if "
|
|
834
|
+
# Check if nat-session already exists in cookies
|
|
835
|
+
if "nat-session=" in cookie_str:
|
|
841
836
|
existing_session_cookie = True
|
|
842
837
|
logger.info("WebSocket: Session cookie already present in headers (same-origin)")
|
|
843
838
|
else:
|
|
@@ -942,10 +937,10 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
942
937
|
|
|
943
938
|
app.add_api_route(
|
|
944
939
|
path=f"{endpoint.path}/async",
|
|
945
|
-
endpoint=post_async_generation(request_type=
|
|
940
|
+
endpoint=post_async_generation(request_type=AsyncGenerateRequest,
|
|
946
941
|
final_result_type=GenerateSingleResponseType),
|
|
947
942
|
methods=[endpoint.method],
|
|
948
|
-
response_model=
|
|
943
|
+
response_model=AsyncGenerateResponse | AsyncGenerationStatusResponse,
|
|
949
944
|
description="Start an async generate job",
|
|
950
945
|
responses={500: response_500},
|
|
951
946
|
)
|
|
@@ -956,7 +951,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
956
951
|
path=f"{endpoint.path}/async/job/{{job_id}}",
|
|
957
952
|
endpoint=get_async_job_status,
|
|
958
953
|
methods=["GET"],
|
|
959
|
-
response_model=
|
|
954
|
+
response_model=AsyncGenerationStatusResponse,
|
|
960
955
|
description="Get the status of an async job",
|
|
961
956
|
responses={
|
|
962
957
|
404: {
|
|
@@ -970,9 +965,9 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
970
965
|
|
|
971
966
|
app.add_api_route(
|
|
972
967
|
path=endpoint.openai_api_path,
|
|
973
|
-
endpoint=get_single_endpoint(result_type=
|
|
968
|
+
endpoint=get_single_endpoint(result_type=ChatResponse),
|
|
974
969
|
methods=[endpoint.method],
|
|
975
|
-
response_model=
|
|
970
|
+
response_model=ChatResponse,
|
|
976
971
|
description=endpoint.description,
|
|
977
972
|
responses={500: response_500},
|
|
978
973
|
)
|
|
@@ -980,10 +975,10 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
980
975
|
app.add_api_route(
|
|
981
976
|
path=f"{endpoint.openai_api_path}/stream",
|
|
982
977
|
endpoint=get_streaming_endpoint(streaming=True,
|
|
983
|
-
result_type=
|
|
984
|
-
output_type=
|
|
978
|
+
result_type=ChatResponseChunk,
|
|
979
|
+
output_type=ChatResponseChunk),
|
|
985
980
|
methods=[endpoint.method],
|
|
986
|
-
response_model=
|
|
981
|
+
response_model=ChatResponseChunk,
|
|
987
982
|
description=endpoint.description,
|
|
988
983
|
responses={500: response_500},
|
|
989
984
|
)
|
|
@@ -998,9 +993,9 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
998
993
|
# <openai_api_path> = non-streaming (legacy behavior)
|
|
999
994
|
app.add_api_route(
|
|
1000
995
|
path=endpoint.openai_api_path,
|
|
1001
|
-
endpoint=post_single_endpoint(request_type=
|
|
996
|
+
endpoint=post_single_endpoint(request_type=ChatRequest, result_type=ChatResponse),
|
|
1002
997
|
methods=[endpoint.method],
|
|
1003
|
-
response_model=
|
|
998
|
+
response_model=ChatResponse,
|
|
1004
999
|
description=endpoint.description,
|
|
1005
1000
|
responses={500: response_500},
|
|
1006
1001
|
)
|
|
@@ -1008,12 +1003,12 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
1008
1003
|
# <openai_api_path>/stream = streaming (legacy behavior)
|
|
1009
1004
|
app.add_api_route(
|
|
1010
1005
|
path=f"{endpoint.openai_api_path}/stream",
|
|
1011
|
-
endpoint=post_streaming_endpoint(request_type=
|
|
1006
|
+
endpoint=post_streaming_endpoint(request_type=ChatRequest,
|
|
1012
1007
|
streaming=True,
|
|
1013
|
-
result_type=
|
|
1014
|
-
output_type=
|
|
1008
|
+
result_type=ChatResponseChunk,
|
|
1009
|
+
output_type=ChatResponseChunk),
|
|
1015
1010
|
methods=[endpoint.method],
|
|
1016
|
-
response_model=
|
|
1011
|
+
response_model=ChatResponseChunk | ResponseIntermediateStep,
|
|
1017
1012
|
description=endpoint.description,
|
|
1018
1013
|
responses={500: response_500},
|
|
1019
1014
|
)
|
|
@@ -1023,9 +1018,9 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
1023
1018
|
# OpenAI v1 Compatible Mode: Create single endpoint that handles both streaming and non-streaming
|
|
1024
1019
|
app.add_api_route(
|
|
1025
1020
|
path=openai_v1_path,
|
|
1026
|
-
endpoint=post_openai_api_compatible_endpoint(request_type=
|
|
1021
|
+
endpoint=post_openai_api_compatible_endpoint(request_type=ChatRequest),
|
|
1027
1022
|
methods=[endpoint.method],
|
|
1028
|
-
response_model=
|
|
1023
|
+
response_model=ChatResponse | ChatResponseChunk,
|
|
1029
1024
|
description=f"{endpoint.description} (OpenAI Chat Completions API compatible)",
|
|
1030
1025
|
responses={500: response_500},
|
|
1031
1026
|
)
|
|
@@ -1037,7 +1032,7 @@ class FastApiFrontEndPluginWorker(FastApiFrontEndPluginWorkerBase):
|
|
|
1037
1032
|
|
|
1038
1033
|
from fastapi.responses import HTMLResponse
|
|
1039
1034
|
|
|
1040
|
-
from
|
|
1035
|
+
from nat.front_ends.fastapi.html_snippets.auth_code_grant_success import AUTH_REDIRECT_SUCCESS_HTML
|
|
1041
1036
|
|
|
1042
1037
|
async def redirect_uri(request: Request):
|
|
1043
1038
|
"""
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
import asyncio
|
|
17
17
|
import logging
|
|
18
18
|
|
|
19
|
-
from
|
|
20
|
-
from
|
|
21
|
-
from
|
|
19
|
+
from nat.builder.context import Context
|
|
20
|
+
from nat.data_models.api_server import ResponseIntermediateStep
|
|
21
|
+
from nat.data_models.intermediate_step import IntermediateStep
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
@@ -30,7 +30,7 @@ async def pull_intermediate(_q, adapter):
|
|
|
30
30
|
results to `_q`.
|
|
31
31
|
"""
|
|
32
32
|
intermediate_done = asyncio.Event()
|
|
33
|
-
context =
|
|
33
|
+
context = Context.get()
|
|
34
34
|
loop = asyncio.get_running_loop()
|
|
35
35
|
|
|
36
36
|
async def set_intermediate_done():
|
|
@@ -41,14 +41,14 @@ async def pull_intermediate(_q, adapter):
|
|
|
41
41
|
Synchronously called whenever the runner publishes an event.
|
|
42
42
|
We process it, then place it into the async queue (via a small async task).
|
|
43
43
|
If adapter is None, convert the raw IntermediateStep into the complete
|
|
44
|
-
|
|
44
|
+
ResponseIntermediateStep and place it into the queue.
|
|
45
45
|
"""
|
|
46
46
|
if adapter is None:
|
|
47
|
-
adapted =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
47
|
+
adapted = ResponseIntermediateStep(id=item.UUID,
|
|
48
|
+
type=item.event_type,
|
|
49
|
+
name=item.name or "",
|
|
50
|
+
parent_id=item.parent_id,
|
|
51
|
+
payload=item.payload.model_dump_json())
|
|
52
52
|
else:
|
|
53
53
|
adapted = adapter.process(item)
|
|
54
54
|
|
|
@@ -17,22 +17,22 @@ import importlib
|
|
|
17
17
|
import logging
|
|
18
18
|
import os
|
|
19
19
|
|
|
20
|
-
from
|
|
21
|
-
from
|
|
20
|
+
from nat.front_ends.fastapi.fastapi_front_end_plugin_worker import FastApiFrontEndPluginWorkerBase
|
|
21
|
+
from nat.runtime.loader import load_config
|
|
22
22
|
|
|
23
23
|
logger = logging.getLogger(__name__)
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
def get_app():
|
|
27
27
|
|
|
28
|
-
config_file_path = os.getenv("
|
|
29
|
-
front_end_worker_full_name = os.getenv("
|
|
28
|
+
config_file_path = os.getenv("NAT_CONFIG_FILE")
|
|
29
|
+
front_end_worker_full_name = os.getenv("NAT_FRONT_END_WORKER")
|
|
30
30
|
|
|
31
31
|
if (not config_file_path):
|
|
32
|
-
raise ValueError("Config file not found in environment variable
|
|
32
|
+
raise ValueError("Config file not found in environment variable NAT_CONFIG_FILE.")
|
|
33
33
|
|
|
34
34
|
if (not front_end_worker_full_name):
|
|
35
|
-
raise ValueError("Front end worker not found in environment variable
|
|
35
|
+
raise ValueError("Front end worker not found in environment variable NAT_FRONT_END_WORKER.")
|
|
36
36
|
|
|
37
37
|
# Try to import the front end worker class
|
|
38
38
|
try:
|
|
@@ -62,9 +62,9 @@ def get_app():
|
|
|
62
62
|
# Create an instance of the front end worker class
|
|
63
63
|
front_end_worker = front_end_worker_class(config)
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
nat_app = front_end_worker.build_app()
|
|
66
66
|
|
|
67
|
-
return
|
|
67
|
+
return nat_app
|
|
68
68
|
|
|
69
69
|
except ImportError as e:
|
|
70
70
|
raise ValueError(f"Front end worker {front_end_worker_full_name} not found.") from e
|