aiqtoolkit 1.2.0rc4__py3-none-any.whl → 1.2.0rc5__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.

Potentially problematic release.


This version of aiqtoolkit might be problematic. Click here for more details.

Files changed (441) hide show
  1. aiqtoolkit-1.2.0rc5.dist-info/METADATA +29 -0
  2. aiqtoolkit-1.2.0rc5.dist-info/RECORD +4 -0
  3. aiqtoolkit-1.2.0rc5.dist-info/top_level.txt +1 -0
  4. aiq/agent/__init__.py +0 -0
  5. aiq/agent/base.py +0 -239
  6. aiq/agent/dual_node.py +0 -67
  7. aiq/agent/react_agent/__init__.py +0 -0
  8. aiq/agent/react_agent/agent.py +0 -355
  9. aiq/agent/react_agent/output_parser.py +0 -104
  10. aiq/agent/react_agent/prompt.py +0 -41
  11. aiq/agent/react_agent/register.py +0 -149
  12. aiq/agent/reasoning_agent/__init__.py +0 -0
  13. aiq/agent/reasoning_agent/reasoning_agent.py +0 -225
  14. aiq/agent/register.py +0 -23
  15. aiq/agent/rewoo_agent/__init__.py +0 -0
  16. aiq/agent/rewoo_agent/agent.py +0 -411
  17. aiq/agent/rewoo_agent/prompt.py +0 -108
  18. aiq/agent/rewoo_agent/register.py +0 -158
  19. aiq/agent/tool_calling_agent/__init__.py +0 -0
  20. aiq/agent/tool_calling_agent/agent.py +0 -119
  21. aiq/agent/tool_calling_agent/register.py +0 -106
  22. aiq/authentication/__init__.py +0 -14
  23. aiq/authentication/api_key/__init__.py +0 -14
  24. aiq/authentication/api_key/api_key_auth_provider.py +0 -96
  25. aiq/authentication/api_key/api_key_auth_provider_config.py +0 -124
  26. aiq/authentication/api_key/register.py +0 -26
  27. aiq/authentication/exceptions/__init__.py +0 -14
  28. aiq/authentication/exceptions/api_key_exceptions.py +0 -38
  29. aiq/authentication/exceptions/auth_code_grant_exceptions.py +0 -86
  30. aiq/authentication/exceptions/call_back_exceptions.py +0 -38
  31. aiq/authentication/exceptions/request_exceptions.py +0 -54
  32. aiq/authentication/http_basic_auth/__init__.py +0 -0
  33. aiq/authentication/http_basic_auth/http_basic_auth_provider.py +0 -81
  34. aiq/authentication/http_basic_auth/register.py +0 -30
  35. aiq/authentication/interfaces.py +0 -93
  36. aiq/authentication/oauth2/__init__.py +0 -14
  37. aiq/authentication/oauth2/oauth2_auth_code_flow_provider.py +0 -107
  38. aiq/authentication/oauth2/oauth2_auth_code_flow_provider_config.py +0 -39
  39. aiq/authentication/oauth2/register.py +0 -25
  40. aiq/authentication/register.py +0 -21
  41. aiq/builder/__init__.py +0 -0
  42. aiq/builder/builder.py +0 -285
  43. aiq/builder/component_utils.py +0 -316
  44. aiq/builder/context.py +0 -264
  45. aiq/builder/embedder.py +0 -24
  46. aiq/builder/eval_builder.py +0 -161
  47. aiq/builder/evaluator.py +0 -29
  48. aiq/builder/framework_enum.py +0 -24
  49. aiq/builder/front_end.py +0 -73
  50. aiq/builder/function.py +0 -344
  51. aiq/builder/function_base.py +0 -380
  52. aiq/builder/function_info.py +0 -627
  53. aiq/builder/intermediate_step_manager.py +0 -174
  54. aiq/builder/llm.py +0 -25
  55. aiq/builder/retriever.py +0 -25
  56. aiq/builder/user_interaction_manager.py +0 -74
  57. aiq/builder/workflow.py +0 -148
  58. aiq/builder/workflow_builder.py +0 -1117
  59. aiq/cli/__init__.py +0 -14
  60. aiq/cli/cli_utils/__init__.py +0 -0
  61. aiq/cli/cli_utils/config_override.py +0 -231
  62. aiq/cli/cli_utils/validation.py +0 -37
  63. aiq/cli/commands/__init__.py +0 -0
  64. aiq/cli/commands/configure/__init__.py +0 -0
  65. aiq/cli/commands/configure/channel/__init__.py +0 -0
  66. aiq/cli/commands/configure/channel/add.py +0 -28
  67. aiq/cli/commands/configure/channel/channel.py +0 -36
  68. aiq/cli/commands/configure/channel/remove.py +0 -30
  69. aiq/cli/commands/configure/channel/update.py +0 -30
  70. aiq/cli/commands/configure/configure.py +0 -33
  71. aiq/cli/commands/evaluate.py +0 -139
  72. aiq/cli/commands/info/__init__.py +0 -14
  73. aiq/cli/commands/info/info.py +0 -39
  74. aiq/cli/commands/info/list_channels.py +0 -32
  75. aiq/cli/commands/info/list_components.py +0 -129
  76. aiq/cli/commands/info/list_mcp.py +0 -213
  77. aiq/cli/commands/registry/__init__.py +0 -14
  78. aiq/cli/commands/registry/publish.py +0 -88
  79. aiq/cli/commands/registry/pull.py +0 -118
  80. aiq/cli/commands/registry/registry.py +0 -38
  81. aiq/cli/commands/registry/remove.py +0 -108
  82. aiq/cli/commands/registry/search.py +0 -155
  83. aiq/cli/commands/sizing/__init__.py +0 -14
  84. aiq/cli/commands/sizing/calc.py +0 -297
  85. aiq/cli/commands/sizing/sizing.py +0 -27
  86. aiq/cli/commands/start.py +0 -246
  87. aiq/cli/commands/uninstall.py +0 -81
  88. aiq/cli/commands/validate.py +0 -47
  89. aiq/cli/commands/workflow/__init__.py +0 -14
  90. aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
  91. aiq/cli/commands/workflow/templates/config.yml.j2 +0 -16
  92. aiq/cli/commands/workflow/templates/pyproject.toml.j2 +0 -22
  93. aiq/cli/commands/workflow/templates/register.py.j2 +0 -5
  94. aiq/cli/commands/workflow/templates/workflow.py.j2 +0 -36
  95. aiq/cli/commands/workflow/workflow.py +0 -37
  96. aiq/cli/commands/workflow/workflow_commands.py +0 -313
  97. aiq/cli/entrypoint.py +0 -135
  98. aiq/cli/main.py +0 -44
  99. aiq/cli/register_workflow.py +0 -488
  100. aiq/cli/type_registry.py +0 -1000
  101. aiq/data_models/__init__.py +0 -14
  102. aiq/data_models/api_server.py +0 -694
  103. aiq/data_models/authentication.py +0 -231
  104. aiq/data_models/common.py +0 -171
  105. aiq/data_models/component.py +0 -54
  106. aiq/data_models/component_ref.py +0 -168
  107. aiq/data_models/config.py +0 -406
  108. aiq/data_models/dataset_handler.py +0 -123
  109. aiq/data_models/discovery_metadata.py +0 -335
  110. aiq/data_models/embedder.py +0 -27
  111. aiq/data_models/evaluate.py +0 -127
  112. aiq/data_models/evaluator.py +0 -26
  113. aiq/data_models/front_end.py +0 -26
  114. aiq/data_models/function.py +0 -30
  115. aiq/data_models/function_dependencies.py +0 -72
  116. aiq/data_models/interactive.py +0 -246
  117. aiq/data_models/intermediate_step.py +0 -302
  118. aiq/data_models/invocation_node.py +0 -38
  119. aiq/data_models/its_strategy.py +0 -30
  120. aiq/data_models/llm.py +0 -27
  121. aiq/data_models/logging.py +0 -26
  122. aiq/data_models/memory.py +0 -27
  123. aiq/data_models/object_store.py +0 -44
  124. aiq/data_models/profiler.py +0 -54
  125. aiq/data_models/registry_handler.py +0 -26
  126. aiq/data_models/retriever.py +0 -30
  127. aiq/data_models/retry_mixin.py +0 -35
  128. aiq/data_models/span.py +0 -187
  129. aiq/data_models/step_adaptor.py +0 -64
  130. aiq/data_models/streaming.py +0 -33
  131. aiq/data_models/swe_bench_model.py +0 -54
  132. aiq/data_models/telemetry_exporter.py +0 -26
  133. aiq/embedder/__init__.py +0 -0
  134. aiq/embedder/langchain_client.py +0 -41
  135. aiq/embedder/nim_embedder.py +0 -59
  136. aiq/embedder/openai_embedder.py +0 -43
  137. aiq/embedder/register.py +0 -24
  138. aiq/eval/__init__.py +0 -14
  139. aiq/eval/config.py +0 -60
  140. aiq/eval/dataset_handler/__init__.py +0 -0
  141. aiq/eval/dataset_handler/dataset_downloader.py +0 -106
  142. aiq/eval/dataset_handler/dataset_filter.py +0 -52
  143. aiq/eval/dataset_handler/dataset_handler.py +0 -254
  144. aiq/eval/evaluate.py +0 -506
  145. aiq/eval/evaluator/__init__.py +0 -14
  146. aiq/eval/evaluator/base_evaluator.py +0 -73
  147. aiq/eval/evaluator/evaluator_model.py +0 -45
  148. aiq/eval/intermediate_step_adapter.py +0 -99
  149. aiq/eval/rag_evaluator/__init__.py +0 -0
  150. aiq/eval/rag_evaluator/evaluate.py +0 -178
  151. aiq/eval/rag_evaluator/register.py +0 -143
  152. aiq/eval/register.py +0 -23
  153. aiq/eval/remote_workflow.py +0 -133
  154. aiq/eval/runners/__init__.py +0 -14
  155. aiq/eval/runners/config.py +0 -39
  156. aiq/eval/runners/multi_eval_runner.py +0 -54
  157. aiq/eval/runtime_event_subscriber.py +0 -52
  158. aiq/eval/swe_bench_evaluator/__init__.py +0 -0
  159. aiq/eval/swe_bench_evaluator/evaluate.py +0 -215
  160. aiq/eval/swe_bench_evaluator/register.py +0 -36
  161. aiq/eval/trajectory_evaluator/__init__.py +0 -0
  162. aiq/eval/trajectory_evaluator/evaluate.py +0 -75
  163. aiq/eval/trajectory_evaluator/register.py +0 -40
  164. aiq/eval/tunable_rag_evaluator/__init__.py +0 -0
  165. aiq/eval/tunable_rag_evaluator/evaluate.py +0 -245
  166. aiq/eval/tunable_rag_evaluator/register.py +0 -52
  167. aiq/eval/usage_stats.py +0 -41
  168. aiq/eval/utils/__init__.py +0 -0
  169. aiq/eval/utils/output_uploader.py +0 -140
  170. aiq/eval/utils/tqdm_position_registry.py +0 -40
  171. aiq/eval/utils/weave_eval.py +0 -184
  172. aiq/experimental/__init__.py +0 -0
  173. aiq/experimental/decorators/__init__.py +0 -0
  174. aiq/experimental/decorators/experimental_warning_decorator.py +0 -130
  175. aiq/experimental/inference_time_scaling/__init__.py +0 -0
  176. aiq/experimental/inference_time_scaling/editing/__init__.py +0 -0
  177. aiq/experimental/inference_time_scaling/editing/iterative_plan_refinement_editor.py +0 -147
  178. aiq/experimental/inference_time_scaling/editing/llm_as_a_judge_editor.py +0 -204
  179. aiq/experimental/inference_time_scaling/editing/motivation_aware_summarization.py +0 -107
  180. aiq/experimental/inference_time_scaling/functions/__init__.py +0 -0
  181. aiq/experimental/inference_time_scaling/functions/execute_score_select_function.py +0 -105
  182. aiq/experimental/inference_time_scaling/functions/its_tool_orchestration_function.py +0 -205
  183. aiq/experimental/inference_time_scaling/functions/its_tool_wrapper_function.py +0 -146
  184. aiq/experimental/inference_time_scaling/functions/plan_select_execute_function.py +0 -224
  185. aiq/experimental/inference_time_scaling/models/__init__.py +0 -0
  186. aiq/experimental/inference_time_scaling/models/editor_config.py +0 -132
  187. aiq/experimental/inference_time_scaling/models/its_item.py +0 -48
  188. aiq/experimental/inference_time_scaling/models/scoring_config.py +0 -112
  189. aiq/experimental/inference_time_scaling/models/search_config.py +0 -120
  190. aiq/experimental/inference_time_scaling/models/selection_config.py +0 -154
  191. aiq/experimental/inference_time_scaling/models/stage_enums.py +0 -43
  192. aiq/experimental/inference_time_scaling/models/strategy_base.py +0 -66
  193. aiq/experimental/inference_time_scaling/models/tool_use_config.py +0 -41
  194. aiq/experimental/inference_time_scaling/register.py +0 -36
  195. aiq/experimental/inference_time_scaling/scoring/__init__.py +0 -0
  196. aiq/experimental/inference_time_scaling/scoring/llm_based_agent_scorer.py +0 -168
  197. aiq/experimental/inference_time_scaling/scoring/llm_based_plan_scorer.py +0 -168
  198. aiq/experimental/inference_time_scaling/scoring/motivation_aware_scorer.py +0 -111
  199. aiq/experimental/inference_time_scaling/search/__init__.py +0 -0
  200. aiq/experimental/inference_time_scaling/search/multi_llm_planner.py +0 -128
  201. aiq/experimental/inference_time_scaling/search/multi_query_retrieval_search.py +0 -122
  202. aiq/experimental/inference_time_scaling/search/single_shot_multi_plan_planner.py +0 -128
  203. aiq/experimental/inference_time_scaling/selection/__init__.py +0 -0
  204. aiq/experimental/inference_time_scaling/selection/best_of_n_selector.py +0 -63
  205. aiq/experimental/inference_time_scaling/selection/llm_based_agent_output_selector.py +0 -131
  206. aiq/experimental/inference_time_scaling/selection/llm_based_output_merging_selector.py +0 -159
  207. aiq/experimental/inference_time_scaling/selection/llm_based_plan_selector.py +0 -128
  208. aiq/experimental/inference_time_scaling/selection/threshold_selector.py +0 -58
  209. aiq/front_ends/__init__.py +0 -14
  210. aiq/front_ends/console/__init__.py +0 -14
  211. aiq/front_ends/console/authentication_flow_handler.py +0 -233
  212. aiq/front_ends/console/console_front_end_config.py +0 -32
  213. aiq/front_ends/console/console_front_end_plugin.py +0 -96
  214. aiq/front_ends/console/register.py +0 -25
  215. aiq/front_ends/cron/__init__.py +0 -14
  216. aiq/front_ends/fastapi/__init__.py +0 -14
  217. aiq/front_ends/fastapi/auth_flow_handlers/__init__.py +0 -0
  218. aiq/front_ends/fastapi/auth_flow_handlers/http_flow_handler.py +0 -27
  219. aiq/front_ends/fastapi/auth_flow_handlers/websocket_flow_handler.py +0 -107
  220. aiq/front_ends/fastapi/fastapi_front_end_config.py +0 -234
  221. aiq/front_ends/fastapi/fastapi_front_end_controller.py +0 -68
  222. aiq/front_ends/fastapi/fastapi_front_end_plugin.py +0 -116
  223. aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +0 -1092
  224. aiq/front_ends/fastapi/html_snippets/__init__.py +0 -14
  225. aiq/front_ends/fastapi/html_snippets/auth_code_grant_success.py +0 -35
  226. aiq/front_ends/fastapi/intermediate_steps_subscriber.py +0 -80
  227. aiq/front_ends/fastapi/job_store.py +0 -183
  228. aiq/front_ends/fastapi/main.py +0 -72
  229. aiq/front_ends/fastapi/message_handler.py +0 -298
  230. aiq/front_ends/fastapi/message_validator.py +0 -345
  231. aiq/front_ends/fastapi/register.py +0 -25
  232. aiq/front_ends/fastapi/response_helpers.py +0 -195
  233. aiq/front_ends/fastapi/step_adaptor.py +0 -321
  234. aiq/front_ends/mcp/__init__.py +0 -14
  235. aiq/front_ends/mcp/mcp_front_end_config.py +0 -32
  236. aiq/front_ends/mcp/mcp_front_end_plugin.py +0 -93
  237. aiq/front_ends/mcp/register.py +0 -27
  238. aiq/front_ends/mcp/tool_converter.py +0 -242
  239. aiq/front_ends/register.py +0 -22
  240. aiq/front_ends/simple_base/__init__.py +0 -14
  241. aiq/front_ends/simple_base/simple_front_end_plugin_base.py +0 -54
  242. aiq/llm/__init__.py +0 -0
  243. aiq/llm/aws_bedrock_llm.py +0 -57
  244. aiq/llm/nim_llm.py +0 -46
  245. aiq/llm/openai_llm.py +0 -46
  246. aiq/llm/register.py +0 -23
  247. aiq/llm/utils/__init__.py +0 -14
  248. aiq/llm/utils/env_config_value.py +0 -94
  249. aiq/llm/utils/error.py +0 -17
  250. aiq/memory/__init__.py +0 -20
  251. aiq/memory/interfaces.py +0 -183
  252. aiq/memory/models.py +0 -112
  253. aiq/meta/module_to_distro.json +0 -3
  254. aiq/meta/pypi.md +0 -58
  255. aiq/object_store/__init__.py +0 -20
  256. aiq/object_store/in_memory_object_store.py +0 -76
  257. aiq/object_store/interfaces.py +0 -84
  258. aiq/object_store/models.py +0 -36
  259. aiq/object_store/register.py +0 -20
  260. aiq/observability/__init__.py +0 -14
  261. aiq/observability/exporter/__init__.py +0 -14
  262. aiq/observability/exporter/base_exporter.py +0 -449
  263. aiq/observability/exporter/exporter.py +0 -78
  264. aiq/observability/exporter/file_exporter.py +0 -33
  265. aiq/observability/exporter/processing_exporter.py +0 -322
  266. aiq/observability/exporter/raw_exporter.py +0 -52
  267. aiq/observability/exporter/span_exporter.py +0 -265
  268. aiq/observability/exporter_manager.py +0 -335
  269. aiq/observability/mixin/__init__.py +0 -14
  270. aiq/observability/mixin/batch_config_mixin.py +0 -26
  271. aiq/observability/mixin/collector_config_mixin.py +0 -23
  272. aiq/observability/mixin/file_mixin.py +0 -288
  273. aiq/observability/mixin/file_mode.py +0 -23
  274. aiq/observability/mixin/resource_conflict_mixin.py +0 -134
  275. aiq/observability/mixin/serialize_mixin.py +0 -61
  276. aiq/observability/mixin/type_introspection_mixin.py +0 -183
  277. aiq/observability/processor/__init__.py +0 -14
  278. aiq/observability/processor/batching_processor.py +0 -309
  279. aiq/observability/processor/callback_processor.py +0 -42
  280. aiq/observability/processor/intermediate_step_serializer.py +0 -28
  281. aiq/observability/processor/processor.py +0 -71
  282. aiq/observability/register.py +0 -96
  283. aiq/observability/utils/__init__.py +0 -14
  284. aiq/observability/utils/dict_utils.py +0 -236
  285. aiq/observability/utils/time_utils.py +0 -31
  286. aiq/plugins/.namespace +0 -1
  287. aiq/profiler/__init__.py +0 -0
  288. aiq/profiler/calc/__init__.py +0 -14
  289. aiq/profiler/calc/calc_runner.py +0 -627
  290. aiq/profiler/calc/calculations.py +0 -288
  291. aiq/profiler/calc/data_models.py +0 -188
  292. aiq/profiler/calc/plot.py +0 -345
  293. aiq/profiler/callbacks/__init__.py +0 -0
  294. aiq/profiler/callbacks/agno_callback_handler.py +0 -295
  295. aiq/profiler/callbacks/base_callback_class.py +0 -20
  296. aiq/profiler/callbacks/langchain_callback_handler.py +0 -290
  297. aiq/profiler/callbacks/llama_index_callback_handler.py +0 -205
  298. aiq/profiler/callbacks/semantic_kernel_callback_handler.py +0 -238
  299. aiq/profiler/callbacks/token_usage_base_model.py +0 -27
  300. aiq/profiler/data_frame_row.py +0 -51
  301. aiq/profiler/data_models.py +0 -24
  302. aiq/profiler/decorators/__init__.py +0 -0
  303. aiq/profiler/decorators/framework_wrapper.py +0 -131
  304. aiq/profiler/decorators/function_tracking.py +0 -254
  305. aiq/profiler/forecasting/__init__.py +0 -0
  306. aiq/profiler/forecasting/config.py +0 -18
  307. aiq/profiler/forecasting/model_trainer.py +0 -75
  308. aiq/profiler/forecasting/models/__init__.py +0 -22
  309. aiq/profiler/forecasting/models/forecasting_base_model.py +0 -40
  310. aiq/profiler/forecasting/models/linear_model.py +0 -196
  311. aiq/profiler/forecasting/models/random_forest_regressor.py +0 -268
  312. aiq/profiler/inference_metrics_model.py +0 -28
  313. aiq/profiler/inference_optimization/__init__.py +0 -0
  314. aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
  315. aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +0 -460
  316. aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +0 -258
  317. aiq/profiler/inference_optimization/data_models.py +0 -386
  318. aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
  319. aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +0 -468
  320. aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +0 -405
  321. aiq/profiler/inference_optimization/llm_metrics.py +0 -212
  322. aiq/profiler/inference_optimization/prompt_caching.py +0 -163
  323. aiq/profiler/inference_optimization/token_uniqueness.py +0 -107
  324. aiq/profiler/inference_optimization/workflow_runtimes.py +0 -72
  325. aiq/profiler/intermediate_property_adapter.py +0 -102
  326. aiq/profiler/profile_runner.py +0 -473
  327. aiq/profiler/utils.py +0 -184
  328. aiq/registry_handlers/__init__.py +0 -0
  329. aiq/registry_handlers/local/__init__.py +0 -0
  330. aiq/registry_handlers/local/local_handler.py +0 -176
  331. aiq/registry_handlers/local/register_local.py +0 -37
  332. aiq/registry_handlers/metadata_factory.py +0 -60
  333. aiq/registry_handlers/package_utils.py +0 -567
  334. aiq/registry_handlers/pypi/__init__.py +0 -0
  335. aiq/registry_handlers/pypi/pypi_handler.py +0 -251
  336. aiq/registry_handlers/pypi/register_pypi.py +0 -40
  337. aiq/registry_handlers/register.py +0 -21
  338. aiq/registry_handlers/registry_handler_base.py +0 -157
  339. aiq/registry_handlers/rest/__init__.py +0 -0
  340. aiq/registry_handlers/rest/register_rest.py +0 -56
  341. aiq/registry_handlers/rest/rest_handler.py +0 -237
  342. aiq/registry_handlers/schemas/__init__.py +0 -0
  343. aiq/registry_handlers/schemas/headers.py +0 -42
  344. aiq/registry_handlers/schemas/package.py +0 -68
  345. aiq/registry_handlers/schemas/publish.py +0 -63
  346. aiq/registry_handlers/schemas/pull.py +0 -82
  347. aiq/registry_handlers/schemas/remove.py +0 -36
  348. aiq/registry_handlers/schemas/search.py +0 -91
  349. aiq/registry_handlers/schemas/status.py +0 -47
  350. aiq/retriever/__init__.py +0 -0
  351. aiq/retriever/interface.py +0 -37
  352. aiq/retriever/milvus/__init__.py +0 -14
  353. aiq/retriever/milvus/register.py +0 -81
  354. aiq/retriever/milvus/retriever.py +0 -228
  355. aiq/retriever/models.py +0 -74
  356. aiq/retriever/nemo_retriever/__init__.py +0 -14
  357. aiq/retriever/nemo_retriever/register.py +0 -60
  358. aiq/retriever/nemo_retriever/retriever.py +0 -190
  359. aiq/retriever/register.py +0 -22
  360. aiq/runtime/__init__.py +0 -14
  361. aiq/runtime/loader.py +0 -215
  362. aiq/runtime/runner.py +0 -190
  363. aiq/runtime/session.py +0 -158
  364. aiq/runtime/user_metadata.py +0 -130
  365. aiq/settings/__init__.py +0 -0
  366. aiq/settings/global_settings.py +0 -318
  367. aiq/test/.namespace +0 -1
  368. aiq/tool/__init__.py +0 -0
  369. aiq/tool/chat_completion.py +0 -74
  370. aiq/tool/code_execution/README.md +0 -151
  371. aiq/tool/code_execution/__init__.py +0 -0
  372. aiq/tool/code_execution/code_sandbox.py +0 -267
  373. aiq/tool/code_execution/local_sandbox/.gitignore +0 -1
  374. aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +0 -60
  375. aiq/tool/code_execution/local_sandbox/__init__.py +0 -13
  376. aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +0 -198
  377. aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +0 -6
  378. aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +0 -50
  379. aiq/tool/code_execution/register.py +0 -74
  380. aiq/tool/code_execution/test_code_execution_sandbox.py +0 -414
  381. aiq/tool/code_execution/utils.py +0 -100
  382. aiq/tool/datetime_tools.py +0 -42
  383. aiq/tool/document_search.py +0 -141
  384. aiq/tool/github_tools/__init__.py +0 -0
  385. aiq/tool/github_tools/create_github_commit.py +0 -133
  386. aiq/tool/github_tools/create_github_issue.py +0 -87
  387. aiq/tool/github_tools/create_github_pr.py +0 -106
  388. aiq/tool/github_tools/get_github_file.py +0 -106
  389. aiq/tool/github_tools/get_github_issue.py +0 -166
  390. aiq/tool/github_tools/get_github_pr.py +0 -256
  391. aiq/tool/github_tools/update_github_issue.py +0 -100
  392. aiq/tool/mcp/__init__.py +0 -14
  393. aiq/tool/mcp/exceptions.py +0 -142
  394. aiq/tool/mcp/mcp_client.py +0 -255
  395. aiq/tool/mcp/mcp_tool.py +0 -96
  396. aiq/tool/memory_tools/__init__.py +0 -0
  397. aiq/tool/memory_tools/add_memory_tool.py +0 -79
  398. aiq/tool/memory_tools/delete_memory_tool.py +0 -67
  399. aiq/tool/memory_tools/get_memory_tool.py +0 -72
  400. aiq/tool/nvidia_rag.py +0 -95
  401. aiq/tool/register.py +0 -38
  402. aiq/tool/retriever.py +0 -89
  403. aiq/tool/server_tools.py +0 -66
  404. aiq/utils/__init__.py +0 -0
  405. aiq/utils/data_models/__init__.py +0 -0
  406. aiq/utils/data_models/schema_validator.py +0 -58
  407. aiq/utils/debugging_utils.py +0 -43
  408. aiq/utils/dump_distro_mapping.py +0 -32
  409. aiq/utils/exception_handlers/__init__.py +0 -0
  410. aiq/utils/exception_handlers/automatic_retries.py +0 -289
  411. aiq/utils/exception_handlers/mcp.py +0 -211
  412. aiq/utils/exception_handlers/schemas.py +0 -114
  413. aiq/utils/io/__init__.py +0 -0
  414. aiq/utils/io/model_processing.py +0 -28
  415. aiq/utils/io/yaml_tools.py +0 -119
  416. aiq/utils/log_utils.py +0 -37
  417. aiq/utils/metadata_utils.py +0 -74
  418. aiq/utils/optional_imports.py +0 -142
  419. aiq/utils/producer_consumer_queue.py +0 -178
  420. aiq/utils/reactive/__init__.py +0 -0
  421. aiq/utils/reactive/base/__init__.py +0 -0
  422. aiq/utils/reactive/base/observable_base.py +0 -65
  423. aiq/utils/reactive/base/observer_base.py +0 -55
  424. aiq/utils/reactive/base/subject_base.py +0 -79
  425. aiq/utils/reactive/observable.py +0 -59
  426. aiq/utils/reactive/observer.py +0 -76
  427. aiq/utils/reactive/subject.py +0 -131
  428. aiq/utils/reactive/subscription.py +0 -49
  429. aiq/utils/settings/__init__.py +0 -0
  430. aiq/utils/settings/global_settings.py +0 -197
  431. aiq/utils/string_utils.py +0 -38
  432. aiq/utils/type_converter.py +0 -290
  433. aiq/utils/type_utils.py +0 -484
  434. aiq/utils/url_utils.py +0 -27
  435. aiqtoolkit-1.2.0rc4.dist-info/METADATA +0 -363
  436. aiqtoolkit-1.2.0rc4.dist-info/RECORD +0 -438
  437. aiqtoolkit-1.2.0rc4.dist-info/entry_points.txt +0 -20
  438. aiqtoolkit-1.2.0rc4.dist-info/licenses/LICENSE-3rd-party.txt +0 -3686
  439. aiqtoolkit-1.2.0rc4.dist-info/licenses/LICENSE.md +0 -201
  440. aiqtoolkit-1.2.0rc4.dist-info/top_level.txt +0 -1
  441. {aiqtoolkit-1.2.0rc4.dist-info → aiqtoolkit-1.2.0rc5.dist-info}/WHEEL +0 -0
@@ -1,233 +0,0 @@
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 asyncio
17
- import secrets
18
- import webbrowser
19
- from dataclasses import dataclass
20
- from dataclasses import field
21
-
22
- import click
23
- import pkce
24
- from authlib.integrations.httpx_client import AsyncOAuth2Client
25
- from fastapi import FastAPI
26
- from fastapi import Request
27
-
28
- from aiq.authentication.interfaces import FlowHandlerBase
29
- from aiq.authentication.oauth2.oauth2_auth_code_flow_provider_config import OAuth2AuthCodeFlowProviderConfig
30
- from aiq.data_models.authentication import AuthenticatedContext
31
- from aiq.data_models.authentication import AuthFlowType
32
- from aiq.data_models.authentication import AuthProviderBaseConfig
33
- from aiq.front_ends.fastapi.fastapi_front_end_controller import _FastApiFrontEndController
34
-
35
-
36
- # --------------------------------------------------------------------------- #
37
- # Helpers #
38
- # --------------------------------------------------------------------------- #
39
- @dataclass
40
- class _FlowState:
41
- future: asyncio.Future = field(default_factory=asyncio.Future, init=False)
42
- challenge: str | None = None
43
- verifier: str | None = None
44
- token_url: str | None = None
45
- use_pkce: bool | None = None
46
-
47
-
48
- # --------------------------------------------------------------------------- #
49
- # Main handler #
50
- # --------------------------------------------------------------------------- #
51
- class ConsoleAuthenticationFlowHandler(FlowHandlerBase):
52
- """
53
- Authentication helper for CLI / console environments. Supports:
54
-
55
- • HTTP Basic (username/password)
56
- • OAuth 2 Authorization‑Code with optional PKCE
57
- """
58
-
59
- # ----------------------------- lifecycle ----------------------------- #
60
- def __init__(self) -> None:
61
- super().__init__()
62
- self._server_controller: _FastApiFrontEndController | None = None
63
- self._redirect_app: FastAPI | None = None # ★ NEW
64
- self._flows: dict[str, _FlowState] = {}
65
- self._active_flows = 0
66
- self._server_lock = asyncio.Lock()
67
- self._oauth_client: AsyncOAuth2Client | None = None
68
-
69
- # ----------------------------- public API ---------------------------- #
70
- async def authenticate(
71
- self,
72
- config: AuthProviderBaseConfig,
73
- method: AuthFlowType,
74
- ) -> AuthenticatedContext:
75
- if method == AuthFlowType.HTTP_BASIC:
76
- return self._handle_http_basic()
77
- if method == AuthFlowType.OAUTH2_AUTHORIZATION_CODE:
78
- if (not isinstance(config, OAuth2AuthCodeFlowProviderConfig)):
79
- raise ValueError("Requested OAuth2 Authorization Code Flow but passed invalid config")
80
-
81
- return await self._handle_oauth2_auth_code_flow(config)
82
-
83
- raise NotImplementedError(f"Auth method “{method}” not supported.")
84
-
85
- # --------------------- OAuth2 helper factories ----------------------- #
86
- def construct_oauth_client(self, cfg: OAuth2AuthCodeFlowProviderConfig) -> AsyncOAuth2Client:
87
- """
88
- Separated for easy overriding in tests (to inject ASGITransport).
89
- """
90
- client = AsyncOAuth2Client(
91
- client_id=cfg.client_id,
92
- client_secret=cfg.client_secret,
93
- redirect_uri=cfg.redirect_uri,
94
- scope=" ".join(cfg.scopes) if cfg.scopes else None,
95
- token_endpoint=cfg.token_url,
96
- token_endpoint_auth_method=cfg.token_endpoint_auth_method,
97
- code_challenge_method="S256" if cfg.use_pkce else None,
98
- )
99
- self._oauth_client = client
100
- return client
101
-
102
- # --------------------------- HTTP Basic ------------------------------ #
103
- @staticmethod
104
- def _handle_http_basic() -> AuthenticatedContext:
105
- username = click.prompt("Username", type=str)
106
- password = click.prompt("Password", type=str, hide_input=True)
107
-
108
- import base64
109
- credentials = f"{username}:{password}"
110
- encoded_credentials = base64.b64encode(credentials.encode("utf-8")).decode("ascii")
111
-
112
- return AuthenticatedContext(
113
- headers={"Authorization": f"Bearer {encoded_credentials}"},
114
- metadata={
115
- "username": username, "password": password
116
- },
117
- )
118
-
119
- # --------------------- OAuth2 Authorization‑Code --------------------- #
120
- async def _handle_oauth2_auth_code_flow(self, cfg: OAuth2AuthCodeFlowProviderConfig) -> AuthenticatedContext:
121
- state = secrets.token_urlsafe(16)
122
- flow_state = _FlowState()
123
- client = self.construct_oauth_client(cfg)
124
-
125
- flow_state.token_url = cfg.token_url
126
- flow_state.use_pkce = cfg.use_pkce
127
-
128
- # PKCE bits
129
- if cfg.use_pkce:
130
- verifier, challenge = pkce.generate_pkce_pair()
131
- flow_state.verifier = verifier
132
- flow_state.challenge = challenge
133
-
134
- auth_url, _ = client.create_authorization_url(
135
- cfg.authorization_url,
136
- state=state,
137
- code_verifier=flow_state.verifier if cfg.use_pkce else None,
138
- code_challenge=flow_state.challenge if cfg.use_pkce else None,
139
- **(cfg.authorization_kwargs or {})
140
- )
141
-
142
- # Register flow + maybe spin up redirect handler
143
- async with self._server_lock:
144
- if (not self._redirect_app):
145
- self._redirect_app = await self._build_redirect_app()
146
-
147
- await self._start_redirect_server()
148
-
149
- self._flows[state] = flow_state
150
- self._active_flows += 1
151
-
152
- click.echo("Your browser has been opened for authentication.")
153
- webbrowser.open(auth_url)
154
-
155
- # Wait for the redirect to land
156
- try:
157
- token = await asyncio.wait_for(flow_state.future, timeout=300)
158
- except asyncio.TimeoutError:
159
- raise RuntimeError("Authentication timed out (5 min).")
160
- finally:
161
- async with self._server_lock:
162
- self._flows.pop(state, None)
163
- self._active_flows -= 1
164
-
165
- if self._active_flows == 0:
166
- await self._stop_redirect_server()
167
-
168
- return AuthenticatedContext(
169
- headers={"Authorization": f"Bearer {token['access_token']}"},
170
- metadata={
171
- "expires_at": token.get("expires_at"), "raw_token": token
172
- },
173
- )
174
-
175
- # --------------- redirect server / in‑process app -------------------- #
176
- async def _build_redirect_app(self) -> FastAPI:
177
- """
178
- * If cfg.run_redirect_local_server == True → start a uvicorn server (old behaviour).
179
- * Else → only build the FastAPI app and save it to `self._redirect_app`
180
- for in‑process testing with ASGITransport.
181
- """
182
- app = FastAPI()
183
-
184
- @app.get("/auth/redirect")
185
- async def handle_redirect(request: Request):
186
- state = request.query_params.get("state")
187
- if not state or state not in self._flows:
188
- return "Invalid state; restart authentication."
189
- flow_state = self._flows[state]
190
- try:
191
- token = await self._oauth_client.fetch_token( # type: ignore[arg-type]
192
- url=flow_state.token_url,
193
- authorization_response=str(request.url),
194
- code_verifier=flow_state.verifier if flow_state.use_pkce else None,
195
- state=state,
196
- )
197
- flow_state.future.set_result(token)
198
- except Exception as exc: # noqa: BLE001
199
- flow_state.future.set_exception(exc)
200
- return "Authentication successful – you may close this tab."
201
-
202
- return app
203
-
204
- async def _start_redirect_server(self) -> None:
205
- # If the server is already running, do nothing
206
- if self._server_controller:
207
- return
208
- try:
209
- if not self._redirect_app:
210
- raise RuntimeError("Redirect app not built.")
211
-
212
- self._server_controller = _FastApiFrontEndController(self._redirect_app)
213
-
214
- asyncio.create_task(self._server_controller.start_server(host="localhost", port=8000))
215
-
216
- # Give uvicorn a moment to bind sockets before we return
217
- await asyncio.sleep(0.3)
218
- except Exception as exc: # noqa: BLE001
219
- raise RuntimeError(f"Failed to start redirect server: {exc}") from exc
220
-
221
- async def _stop_redirect_server(self) -> None:
222
- if self._server_controller:
223
- await self._server_controller.stop_server()
224
- self._server_controller = None
225
-
226
- # ------------------------- test helpers ------------------------------ #
227
- @property
228
- def redirect_app(self) -> FastAPI | None:
229
- """
230
- In “test‑mode” (run_redirect_local_server=False) the in‑memory FastAPI
231
- app is exposed so you can mount it on `httpx.ASGITransport`.
232
- """
233
- return self._redirect_app
@@ -1,32 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from pathlib import Path
17
-
18
- from pydantic import Field
19
-
20
- from aiq.data_models.front_end import FrontEndBaseConfig
21
-
22
-
23
- class ConsoleFrontEndConfig(FrontEndBaseConfig, name="console"):
24
- """
25
- A front end that allows an AIQ Toolkit workflow to be run from the console.
26
- """
27
-
28
- input_query: list[str] | None = Field(default=None,
29
- alias="input",
30
- description="A single input to submit the the workflow.")
31
- input_file: Path | None = Field(default=None,
32
- description="Path to a json file of inputs to submit to the workflow.")
@@ -1,96 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- import asyncio
17
- import logging
18
-
19
- import click
20
- from colorama import Fore
21
-
22
- from aiq.data_models.interactive import HumanPromptModelType
23
- from aiq.data_models.interactive import HumanResponse
24
- from aiq.data_models.interactive import HumanResponseText
25
- from aiq.data_models.interactive import InteractionPrompt
26
- from aiq.front_ends.console.authentication_flow_handler import ConsoleAuthenticationFlowHandler
27
- from aiq.front_ends.console.console_front_end_config import ConsoleFrontEndConfig
28
- from aiq.front_ends.simple_base.simple_front_end_plugin_base import SimpleFrontEndPluginBase
29
- from aiq.runtime.session import AIQSessionManager
30
-
31
- logger = logging.getLogger(__name__)
32
-
33
-
34
- async def prompt_for_input_cli(question: InteractionPrompt) -> HumanResponse:
35
- """
36
- A simple CLI-based callback.
37
- Takes question as str, returns the typed line as str.
38
- """
39
-
40
- if question.content.input_type == HumanPromptModelType.TEXT:
41
- user_response = click.prompt(text=question.content.text)
42
-
43
- return HumanResponseText(text=user_response)
44
-
45
- raise ValueError("Unsupported human prompt input type. The run command only supports the 'HumanPromptText' "
46
- "input type. Please use the 'serve' command to ensure full support for all input types.")
47
-
48
-
49
- class ConsoleFrontEndPlugin(SimpleFrontEndPluginBase[ConsoleFrontEndConfig]):
50
-
51
- def __init__(self, full_config):
52
- super().__init__(full_config=full_config)
53
-
54
- # Set the authentication flow handler
55
- self.auth_flow_handler = ConsoleAuthenticationFlowHandler()
56
-
57
- async def pre_run(self):
58
-
59
- if (not self.front_end_config.input_query and not self.front_end_config.input_file):
60
- raise click.UsageError("Must specify either --input_query or --input_file")
61
-
62
- async def run_workflow(self, session_manager: AIQSessionManager):
63
-
64
- assert session_manager is not None, "Session manager must be provided"
65
- runner_outputs = None
66
-
67
- if (self.front_end_config.input_query):
68
-
69
- async def run_single_query(query):
70
-
71
- async with session_manager.session(
72
- user_input_callback=prompt_for_input_cli,
73
- user_authentication_callback=self.auth_flow_handler.authenticate) as session:
74
- async with session.run(query) as runner:
75
- base_output = await runner.result(to_type=str)
76
-
77
- return base_output
78
-
79
- # Convert to a list
80
- input_list = list(self.front_end_config.input_query)
81
- logger.debug("Processing input: %s", self.front_end_config.input_query)
82
-
83
- runner_outputs = await asyncio.gather(*[run_single_query(query) for query in input_list])
84
-
85
- elif (self.front_end_config.input_file):
86
-
87
- # Run the workflow
88
- with open(self.front_end_config.input_file, "r", encoding="utf-8") as f:
89
-
90
- async with session_manager.workflow.run(f) as runner:
91
- runner_outputs = await runner.result(to_type=str)
92
- else:
93
- assert False, "Should not reach here. Should have been caught by pre_run"
94
-
95
- # Print result
96
- logger.info(f"\n{'-' * 50}\n{Fore.GREEN}Workflow Result:\n%s{Fore.RESET}\n{'-' * 50}", runner_outputs)
@@ -1,25 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from aiq.cli.register_workflow import register_front_end
17
- from aiq.data_models.config import AIQConfig
18
- from aiq.front_ends.console.console_front_end_config import ConsoleFrontEndConfig
19
-
20
-
21
- @register_front_end(config_type=ConsoleFrontEndConfig)
22
- async def register_fastapi_front_end(config: ConsoleFrontEndConfig, full_config: AIQConfig):
23
- from aiq.front_ends.console.console_front_end_plugin import ConsoleFrontEndPlugin
24
-
25
- yield ConsoleFrontEndPlugin(full_config=full_config)
@@ -1,14 +0,0 @@
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.
@@ -1,14 +0,0 @@
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.
File without changes
@@ -1,27 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from aiq.authentication.interfaces import FlowHandlerBase
17
- from aiq.data_models.authentication import AuthenticatedContext
18
- from aiq.data_models.authentication import AuthFlowType
19
- from aiq.data_models.authentication import AuthProviderBaseConfig
20
-
21
-
22
- class HTTPAuthenticationFlowHandler(FlowHandlerBase):
23
-
24
- async def authenticate(self, config: AuthProviderBaseConfig, method: AuthFlowType) -> AuthenticatedContext:
25
-
26
- raise NotImplementedError(f"Authentication method '{method}' is not supported by the HTTP frontend."
27
- f" Do you have Websockets enabled?")
@@ -1,107 +0,0 @@
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 asyncio
17
- import logging
18
- import secrets
19
- from collections.abc import Awaitable
20
- from collections.abc import Callable
21
- from dataclasses import dataclass
22
- from dataclasses import field
23
-
24
- import pkce
25
- from authlib.integrations.httpx_client import AsyncOAuth2Client
26
-
27
- from aiq.authentication.interfaces import FlowHandlerBase
28
- from aiq.authentication.oauth2.oauth2_auth_code_flow_provider_config import OAuth2AuthCodeFlowProviderConfig
29
- from aiq.data_models.authentication import AuthenticatedContext
30
- from aiq.data_models.authentication import AuthFlowType
31
- from aiq.data_models.interactive import _HumanPromptOAuthConsent
32
- from aiq.front_ends.fastapi.message_handler import WebSocketMessageHandler
33
-
34
- logger = logging.getLogger(__name__)
35
-
36
-
37
- @dataclass
38
- class FlowState:
39
- future: asyncio.Future = field(default_factory=asyncio.Future, init=False)
40
- challenge: str | None = None
41
- verifier: str | None = None
42
- client: AsyncOAuth2Client | None = None
43
- config: OAuth2AuthCodeFlowProviderConfig | None = None
44
-
45
-
46
- class WebSocketAuthenticationFlowHandler(FlowHandlerBase):
47
-
48
- def __init__(self,
49
- add_flow_cb: Callable[[str, FlowState], Awaitable[None]],
50
- remove_flow_cb: Callable[[str], Awaitable[None]],
51
- web_socket_message_handler: WebSocketMessageHandler):
52
-
53
- self._add_flow_cb: Callable[[str, FlowState], Awaitable[None]] = add_flow_cb
54
- self._remove_flow_cb: Callable[[str], Awaitable[None]] = remove_flow_cb
55
- self._web_socket_message_handler: WebSocketMessageHandler = web_socket_message_handler
56
-
57
- async def authenticate(self, config: OAuth2AuthCodeFlowProviderConfig,
58
- method: AuthFlowType) -> AuthenticatedContext:
59
- if method == AuthFlowType.OAUTH2_AUTHORIZATION_CODE:
60
- return await self._handle_oauth2_auth_code_flow(config)
61
-
62
- raise NotImplementedError(f"Authentication method '{method}' is not supported by the websocket frontend.")
63
-
64
- def create_oauth_client(self, config: OAuth2AuthCodeFlowProviderConfig):
65
- return AsyncOAuth2Client(client_id=config.client_id,
66
- client_secret=config.client_secret,
67
- redirect_uri=config.redirect_uri,
68
- scope=" ".join(config.scopes) if config.scopes else None,
69
- token_endpoint=config.token_url,
70
- code_challenge_method='S256' if config.use_pkce else None,
71
- token_endpoint_auth_method=config.token_endpoint_auth_method)
72
-
73
- async def _handle_oauth2_auth_code_flow(self, config: OAuth2AuthCodeFlowProviderConfig) -> AuthenticatedContext:
74
-
75
- state = secrets.token_urlsafe(16)
76
- flow_state = FlowState(config=config)
77
-
78
- flow_state.client = self.create_oauth_client(config)
79
-
80
- if config.use_pkce:
81
- verifier, challenge = pkce.generate_pkce_pair()
82
- flow_state.verifier = verifier
83
- flow_state.challenge = challenge
84
-
85
- authorization_url, _ = flow_state.client.create_authorization_url(
86
- config.authorization_url,
87
- state=state,
88
- code_verifier=flow_state.verifier if config.use_pkce else None,
89
- code_challenge=flow_state.challenge if config.use_pkce else None,
90
- **(config.authorization_kwargs or {})
91
- )
92
-
93
- await self._add_flow_cb(state, flow_state)
94
- await self._web_socket_message_handler.create_websocket_message(_HumanPromptOAuthConsent(text=authorization_url)
95
- )
96
- try:
97
- token = await asyncio.wait_for(flow_state.future, timeout=300)
98
- except asyncio.TimeoutError:
99
- raise RuntimeError("Authentication flow timed out after 5 minutes.")
100
- finally:
101
-
102
- await self._remove_flow_cb(state)
103
-
104
- return AuthenticatedContext(headers={"Authorization": f"Bearer {token['access_token']}"},
105
- metadata={
106
- "expires_at": token.get("expires_at"), "raw_token": token
107
- })