aiqtoolkit 1.1.0a20250515__py3-none-any.whl → 1.1.0a20251020__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (319) hide show
  1. aiqtoolkit-1.1.0a20251020.dist-info/METADATA +37 -0
  2. aiqtoolkit-1.1.0a20251020.dist-info/RECORD +4 -0
  3. {aiqtoolkit-1.1.0a20250515.dist-info → aiqtoolkit-1.1.0a20251020.dist-info}/WHEEL +1 -1
  4. aiqtoolkit-1.1.0a20251020.dist-info/top_level.txt +1 -0
  5. aiq/agent/__init__.py +0 -0
  6. aiq/agent/base.py +0 -76
  7. aiq/agent/dual_node.py +0 -67
  8. aiq/agent/react_agent/__init__.py +0 -0
  9. aiq/agent/react_agent/agent.py +0 -322
  10. aiq/agent/react_agent/output_parser.py +0 -104
  11. aiq/agent/react_agent/prompt.py +0 -46
  12. aiq/agent/react_agent/register.py +0 -148
  13. aiq/agent/reasoning_agent/__init__.py +0 -0
  14. aiq/agent/reasoning_agent/reasoning_agent.py +0 -224
  15. aiq/agent/register.py +0 -23
  16. aiq/agent/rewoo_agent/__init__.py +0 -0
  17. aiq/agent/rewoo_agent/agent.py +0 -410
  18. aiq/agent/rewoo_agent/prompt.py +0 -108
  19. aiq/agent/rewoo_agent/register.py +0 -158
  20. aiq/agent/tool_calling_agent/__init__.py +0 -0
  21. aiq/agent/tool_calling_agent/agent.py +0 -123
  22. aiq/agent/tool_calling_agent/register.py +0 -105
  23. aiq/builder/__init__.py +0 -0
  24. aiq/builder/builder.py +0 -223
  25. aiq/builder/component_utils.py +0 -303
  26. aiq/builder/context.py +0 -227
  27. aiq/builder/embedder.py +0 -24
  28. aiq/builder/eval_builder.py +0 -120
  29. aiq/builder/evaluator.py +0 -29
  30. aiq/builder/framework_enum.py +0 -24
  31. aiq/builder/front_end.py +0 -73
  32. aiq/builder/function.py +0 -297
  33. aiq/builder/function_base.py +0 -376
  34. aiq/builder/function_info.py +0 -627
  35. aiq/builder/intermediate_step_manager.py +0 -135
  36. aiq/builder/llm.py +0 -25
  37. aiq/builder/retriever.py +0 -25
  38. aiq/builder/user_interaction_manager.py +0 -71
  39. aiq/builder/workflow.py +0 -143
  40. aiq/builder/workflow_builder.py +0 -757
  41. aiq/cli/__init__.py +0 -14
  42. aiq/cli/cli_utils/__init__.py +0 -0
  43. aiq/cli/cli_utils/config_override.py +0 -231
  44. aiq/cli/cli_utils/validation.py +0 -37
  45. aiq/cli/commands/__init__.py +0 -0
  46. aiq/cli/commands/configure/__init__.py +0 -0
  47. aiq/cli/commands/configure/channel/__init__.py +0 -0
  48. aiq/cli/commands/configure/channel/add.py +0 -28
  49. aiq/cli/commands/configure/channel/channel.py +0 -36
  50. aiq/cli/commands/configure/channel/remove.py +0 -30
  51. aiq/cli/commands/configure/channel/update.py +0 -30
  52. aiq/cli/commands/configure/configure.py +0 -33
  53. aiq/cli/commands/evaluate.py +0 -139
  54. aiq/cli/commands/info/__init__.py +0 -14
  55. aiq/cli/commands/info/info.py +0 -39
  56. aiq/cli/commands/info/list_channels.py +0 -32
  57. aiq/cli/commands/info/list_components.py +0 -129
  58. aiq/cli/commands/info/list_mcp.py +0 -126
  59. aiq/cli/commands/registry/__init__.py +0 -14
  60. aiq/cli/commands/registry/publish.py +0 -88
  61. aiq/cli/commands/registry/pull.py +0 -118
  62. aiq/cli/commands/registry/registry.py +0 -38
  63. aiq/cli/commands/registry/remove.py +0 -108
  64. aiq/cli/commands/registry/search.py +0 -155
  65. aiq/cli/commands/start.py +0 -250
  66. aiq/cli/commands/uninstall.py +0 -83
  67. aiq/cli/commands/validate.py +0 -47
  68. aiq/cli/commands/workflow/__init__.py +0 -14
  69. aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
  70. aiq/cli/commands/workflow/templates/config.yml.j2 +0 -16
  71. aiq/cli/commands/workflow/templates/pyproject.toml.j2 +0 -22
  72. aiq/cli/commands/workflow/templates/register.py.j2 +0 -5
  73. aiq/cli/commands/workflow/templates/workflow.py.j2 +0 -36
  74. aiq/cli/commands/workflow/workflow.py +0 -37
  75. aiq/cli/commands/workflow/workflow_commands.py +0 -313
  76. aiq/cli/entrypoint.py +0 -133
  77. aiq/cli/main.py +0 -44
  78. aiq/cli/register_workflow.py +0 -408
  79. aiq/cli/type_registry.py +0 -879
  80. aiq/data_models/__init__.py +0 -14
  81. aiq/data_models/api_server.py +0 -588
  82. aiq/data_models/common.py +0 -143
  83. aiq/data_models/component.py +0 -46
  84. aiq/data_models/component_ref.py +0 -135
  85. aiq/data_models/config.py +0 -349
  86. aiq/data_models/dataset_handler.py +0 -122
  87. aiq/data_models/discovery_metadata.py +0 -286
  88. aiq/data_models/embedder.py +0 -26
  89. aiq/data_models/evaluate.py +0 -104
  90. aiq/data_models/evaluator.py +0 -26
  91. aiq/data_models/front_end.py +0 -26
  92. aiq/data_models/function.py +0 -30
  93. aiq/data_models/function_dependencies.py +0 -64
  94. aiq/data_models/interactive.py +0 -237
  95. aiq/data_models/intermediate_step.py +0 -269
  96. aiq/data_models/invocation_node.py +0 -38
  97. aiq/data_models/llm.py +0 -26
  98. aiq/data_models/logging.py +0 -26
  99. aiq/data_models/memory.py +0 -26
  100. aiq/data_models/profiler.py +0 -53
  101. aiq/data_models/registry_handler.py +0 -26
  102. aiq/data_models/retriever.py +0 -30
  103. aiq/data_models/step_adaptor.py +0 -64
  104. aiq/data_models/streaming.py +0 -33
  105. aiq/data_models/swe_bench_model.py +0 -54
  106. aiq/data_models/telemetry_exporter.py +0 -26
  107. aiq/embedder/__init__.py +0 -0
  108. aiq/embedder/langchain_client.py +0 -41
  109. aiq/embedder/nim_embedder.py +0 -58
  110. aiq/embedder/openai_embedder.py +0 -42
  111. aiq/embedder/register.py +0 -24
  112. aiq/eval/__init__.py +0 -14
  113. aiq/eval/config.py +0 -42
  114. aiq/eval/dataset_handler/__init__.py +0 -0
  115. aiq/eval/dataset_handler/dataset_downloader.py +0 -106
  116. aiq/eval/dataset_handler/dataset_filter.py +0 -52
  117. aiq/eval/dataset_handler/dataset_handler.py +0 -169
  118. aiq/eval/evaluate.py +0 -325
  119. aiq/eval/evaluator/__init__.py +0 -14
  120. aiq/eval/evaluator/evaluator_model.py +0 -44
  121. aiq/eval/intermediate_step_adapter.py +0 -93
  122. aiq/eval/rag_evaluator/__init__.py +0 -0
  123. aiq/eval/rag_evaluator/evaluate.py +0 -138
  124. aiq/eval/rag_evaluator/register.py +0 -138
  125. aiq/eval/register.py +0 -23
  126. aiq/eval/remote_workflow.py +0 -128
  127. aiq/eval/runtime_event_subscriber.py +0 -52
  128. aiq/eval/swe_bench_evaluator/__init__.py +0 -0
  129. aiq/eval/swe_bench_evaluator/evaluate.py +0 -215
  130. aiq/eval/swe_bench_evaluator/register.py +0 -36
  131. aiq/eval/trajectory_evaluator/__init__.py +0 -0
  132. aiq/eval/trajectory_evaluator/evaluate.py +0 -118
  133. aiq/eval/trajectory_evaluator/register.py +0 -40
  134. aiq/eval/tunable_rag_evaluator/__init__.py +0 -0
  135. aiq/eval/tunable_rag_evaluator/evaluate.py +0 -263
  136. aiq/eval/tunable_rag_evaluator/register.py +0 -50
  137. aiq/eval/utils/__init__.py +0 -0
  138. aiq/eval/utils/output_uploader.py +0 -131
  139. aiq/eval/utils/tqdm_position_registry.py +0 -40
  140. aiq/front_ends/__init__.py +0 -14
  141. aiq/front_ends/console/__init__.py +0 -14
  142. aiq/front_ends/console/console_front_end_config.py +0 -32
  143. aiq/front_ends/console/console_front_end_plugin.py +0 -107
  144. aiq/front_ends/console/register.py +0 -25
  145. aiq/front_ends/cron/__init__.py +0 -14
  146. aiq/front_ends/fastapi/__init__.py +0 -14
  147. aiq/front_ends/fastapi/fastapi_front_end_config.py +0 -150
  148. aiq/front_ends/fastapi/fastapi_front_end_plugin.py +0 -103
  149. aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +0 -607
  150. aiq/front_ends/fastapi/intermediate_steps_subscriber.py +0 -80
  151. aiq/front_ends/fastapi/job_store.py +0 -161
  152. aiq/front_ends/fastapi/main.py +0 -70
  153. aiq/front_ends/fastapi/message_handler.py +0 -279
  154. aiq/front_ends/fastapi/message_validator.py +0 -345
  155. aiq/front_ends/fastapi/register.py +0 -25
  156. aiq/front_ends/fastapi/response_helpers.py +0 -195
  157. aiq/front_ends/fastapi/step_adaptor.py +0 -320
  158. aiq/front_ends/fastapi/websocket.py +0 -148
  159. aiq/front_ends/mcp/__init__.py +0 -14
  160. aiq/front_ends/mcp/mcp_front_end_config.py +0 -32
  161. aiq/front_ends/mcp/mcp_front_end_plugin.py +0 -93
  162. aiq/front_ends/mcp/register.py +0 -27
  163. aiq/front_ends/mcp/tool_converter.py +0 -242
  164. aiq/front_ends/register.py +0 -22
  165. aiq/front_ends/simple_base/__init__.py +0 -14
  166. aiq/front_ends/simple_base/simple_front_end_plugin_base.py +0 -52
  167. aiq/llm/__init__.py +0 -0
  168. aiq/llm/nim_llm.py +0 -45
  169. aiq/llm/openai_llm.py +0 -45
  170. aiq/llm/register.py +0 -22
  171. aiq/llm/utils/__init__.py +0 -14
  172. aiq/llm/utils/env_config_value.py +0 -94
  173. aiq/llm/utils/error.py +0 -17
  174. aiq/memory/__init__.py +0 -20
  175. aiq/memory/interfaces.py +0 -183
  176. aiq/memory/models.py +0 -112
  177. aiq/meta/module_to_distro.json +0 -3
  178. aiq/meta/pypi.md +0 -58
  179. aiq/observability/__init__.py +0 -0
  180. aiq/observability/async_otel_listener.py +0 -429
  181. aiq/observability/register.py +0 -99
  182. aiq/plugins/.namespace +0 -1
  183. aiq/profiler/__init__.py +0 -0
  184. aiq/profiler/callbacks/__init__.py +0 -0
  185. aiq/profiler/callbacks/agno_callback_handler.py +0 -295
  186. aiq/profiler/callbacks/base_callback_class.py +0 -20
  187. aiq/profiler/callbacks/langchain_callback_handler.py +0 -278
  188. aiq/profiler/callbacks/llama_index_callback_handler.py +0 -205
  189. aiq/profiler/callbacks/semantic_kernel_callback_handler.py +0 -238
  190. aiq/profiler/callbacks/token_usage_base_model.py +0 -27
  191. aiq/profiler/data_frame_row.py +0 -51
  192. aiq/profiler/decorators/__init__.py +0 -0
  193. aiq/profiler/decorators/framework_wrapper.py +0 -131
  194. aiq/profiler/decorators/function_tracking.py +0 -254
  195. aiq/profiler/forecasting/__init__.py +0 -0
  196. aiq/profiler/forecasting/config.py +0 -18
  197. aiq/profiler/forecasting/model_trainer.py +0 -75
  198. aiq/profiler/forecasting/models/__init__.py +0 -22
  199. aiq/profiler/forecasting/models/forecasting_base_model.py +0 -40
  200. aiq/profiler/forecasting/models/linear_model.py +0 -196
  201. aiq/profiler/forecasting/models/random_forest_regressor.py +0 -268
  202. aiq/profiler/inference_metrics_model.py +0 -25
  203. aiq/profiler/inference_optimization/__init__.py +0 -0
  204. aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
  205. aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +0 -452
  206. aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +0 -258
  207. aiq/profiler/inference_optimization/data_models.py +0 -386
  208. aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
  209. aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +0 -468
  210. aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +0 -405
  211. aiq/profiler/inference_optimization/llm_metrics.py +0 -212
  212. aiq/profiler/inference_optimization/prompt_caching.py +0 -163
  213. aiq/profiler/inference_optimization/token_uniqueness.py +0 -107
  214. aiq/profiler/inference_optimization/workflow_runtimes.py +0 -72
  215. aiq/profiler/intermediate_property_adapter.py +0 -102
  216. aiq/profiler/profile_runner.py +0 -433
  217. aiq/profiler/utils.py +0 -184
  218. aiq/registry_handlers/__init__.py +0 -0
  219. aiq/registry_handlers/local/__init__.py +0 -0
  220. aiq/registry_handlers/local/local_handler.py +0 -176
  221. aiq/registry_handlers/local/register_local.py +0 -37
  222. aiq/registry_handlers/metadata_factory.py +0 -60
  223. aiq/registry_handlers/package_utils.py +0 -198
  224. aiq/registry_handlers/pypi/__init__.py +0 -0
  225. aiq/registry_handlers/pypi/pypi_handler.py +0 -251
  226. aiq/registry_handlers/pypi/register_pypi.py +0 -40
  227. aiq/registry_handlers/register.py +0 -21
  228. aiq/registry_handlers/registry_handler_base.py +0 -157
  229. aiq/registry_handlers/rest/__init__.py +0 -0
  230. aiq/registry_handlers/rest/register_rest.py +0 -56
  231. aiq/registry_handlers/rest/rest_handler.py +0 -237
  232. aiq/registry_handlers/schemas/__init__.py +0 -0
  233. aiq/registry_handlers/schemas/headers.py +0 -42
  234. aiq/registry_handlers/schemas/package.py +0 -68
  235. aiq/registry_handlers/schemas/publish.py +0 -63
  236. aiq/registry_handlers/schemas/pull.py +0 -82
  237. aiq/registry_handlers/schemas/remove.py +0 -36
  238. aiq/registry_handlers/schemas/search.py +0 -91
  239. aiq/registry_handlers/schemas/status.py +0 -47
  240. aiq/retriever/__init__.py +0 -0
  241. aiq/retriever/interface.py +0 -37
  242. aiq/retriever/milvus/__init__.py +0 -14
  243. aiq/retriever/milvus/register.py +0 -81
  244. aiq/retriever/milvus/retriever.py +0 -228
  245. aiq/retriever/models.py +0 -74
  246. aiq/retriever/nemo_retriever/__init__.py +0 -14
  247. aiq/retriever/nemo_retriever/register.py +0 -60
  248. aiq/retriever/nemo_retriever/retriever.py +0 -190
  249. aiq/retriever/register.py +0 -22
  250. aiq/runtime/__init__.py +0 -14
  251. aiq/runtime/loader.py +0 -188
  252. aiq/runtime/runner.py +0 -176
  253. aiq/runtime/session.py +0 -140
  254. aiq/runtime/user_metadata.py +0 -131
  255. aiq/settings/__init__.py +0 -0
  256. aiq/settings/global_settings.py +0 -318
  257. aiq/test/.namespace +0 -1
  258. aiq/tool/__init__.py +0 -0
  259. aiq/tool/code_execution/__init__.py +0 -0
  260. aiq/tool/code_execution/code_sandbox.py +0 -188
  261. aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +0 -60
  262. aiq/tool/code_execution/local_sandbox/__init__.py +0 -13
  263. aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +0 -83
  264. aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +0 -4
  265. aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +0 -25
  266. aiq/tool/code_execution/register.py +0 -70
  267. aiq/tool/code_execution/utils.py +0 -100
  268. aiq/tool/datetime_tools.py +0 -42
  269. aiq/tool/document_search.py +0 -141
  270. aiq/tool/github_tools/__init__.py +0 -0
  271. aiq/tool/github_tools/create_github_commit.py +0 -133
  272. aiq/tool/github_tools/create_github_issue.py +0 -87
  273. aiq/tool/github_tools/create_github_pr.py +0 -106
  274. aiq/tool/github_tools/get_github_file.py +0 -106
  275. aiq/tool/github_tools/get_github_issue.py +0 -166
  276. aiq/tool/github_tools/get_github_pr.py +0 -256
  277. aiq/tool/github_tools/update_github_issue.py +0 -100
  278. aiq/tool/mcp/__init__.py +0 -14
  279. aiq/tool/mcp/mcp_client.py +0 -220
  280. aiq/tool/mcp/mcp_tool.py +0 -95
  281. aiq/tool/memory_tools/__init__.py +0 -0
  282. aiq/tool/memory_tools/add_memory_tool.py +0 -79
  283. aiq/tool/memory_tools/delete_memory_tool.py +0 -67
  284. aiq/tool/memory_tools/get_memory_tool.py +0 -72
  285. aiq/tool/nvidia_rag.py +0 -95
  286. aiq/tool/register.py +0 -37
  287. aiq/tool/retriever.py +0 -89
  288. aiq/tool/server_tools.py +0 -63
  289. aiq/utils/__init__.py +0 -0
  290. aiq/utils/data_models/__init__.py +0 -0
  291. aiq/utils/data_models/schema_validator.py +0 -58
  292. aiq/utils/debugging_utils.py +0 -43
  293. aiq/utils/exception_handlers/__init__.py +0 -0
  294. aiq/utils/exception_handlers/schemas.py +0 -114
  295. aiq/utils/io/__init__.py +0 -0
  296. aiq/utils/io/yaml_tools.py +0 -119
  297. aiq/utils/metadata_utils.py +0 -74
  298. aiq/utils/optional_imports.py +0 -142
  299. aiq/utils/producer_consumer_queue.py +0 -178
  300. aiq/utils/reactive/__init__.py +0 -0
  301. aiq/utils/reactive/base/__init__.py +0 -0
  302. aiq/utils/reactive/base/observable_base.py +0 -65
  303. aiq/utils/reactive/base/observer_base.py +0 -55
  304. aiq/utils/reactive/base/subject_base.py +0 -79
  305. aiq/utils/reactive/observable.py +0 -59
  306. aiq/utils/reactive/observer.py +0 -76
  307. aiq/utils/reactive/subject.py +0 -131
  308. aiq/utils/reactive/subscription.py +0 -49
  309. aiq/utils/settings/__init__.py +0 -0
  310. aiq/utils/settings/global_settings.py +0 -197
  311. aiq/utils/type_converter.py +0 -232
  312. aiq/utils/type_utils.py +0 -397
  313. aiq/utils/url_utils.py +0 -27
  314. aiqtoolkit-1.1.0a20250515.dist-info/METADATA +0 -331
  315. aiqtoolkit-1.1.0a20250515.dist-info/RECORD +0 -316
  316. aiqtoolkit-1.1.0a20250515.dist-info/entry_points.txt +0 -17
  317. aiqtoolkit-1.1.0a20250515.dist-info/licenses/LICENSE-3rd-party.txt +0 -3686
  318. aiqtoolkit-1.1.0a20250515.dist-info/licenses/LICENSE.md +0 -201
  319. aiqtoolkit-1.1.0a20250515.dist-info/top_level.txt +0 -1
aiq/runtime/session.py DELETED
@@ -1,140 +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 contextvars
18
- import typing
19
- from collections.abc import Awaitable
20
- from collections.abc import Callable
21
- from contextlib import asynccontextmanager
22
- from contextlib import nullcontext
23
-
24
- from fastapi import Request
25
-
26
- from aiq.builder.context import AIQContext
27
- from aiq.builder.context import AIQContextState
28
- from aiq.builder.workflow import Workflow
29
- from aiq.data_models.config import AIQConfig
30
- from aiq.data_models.interactive import HumanResponse
31
- from aiq.data_models.interactive import InteractionPrompt
32
-
33
- _T = typing.TypeVar("_T")
34
-
35
-
36
- class UserManagerBase:
37
- pass
38
-
39
-
40
- class AIQSessionManager:
41
-
42
- def __init__(self, workflow: Workflow, max_concurrency: int = 8):
43
- """
44
- The AIQSessionManager class is used to run and manage a user workflow session. It runs and manages the context,
45
- and configuration of a workflow with the specified concurrency.
46
-
47
- Parameters
48
- ----------
49
- workflow : Workflow
50
- The workflow to run
51
- max_concurrency : int, optional
52
- The maximum number of simultaneous workflow invocations, by default 8
53
- """
54
-
55
- if (workflow is None):
56
- raise ValueError("Workflow cannot be None")
57
-
58
- self._workflow: Workflow = workflow
59
-
60
- self._max_concurrency = max_concurrency
61
- self._context_state = AIQContextState.get()
62
- self._context = AIQContext(self._context_state)
63
-
64
- # We save the context because Uvicorn spawns a new process
65
- # for each request, and we need to restore the context vars
66
- self._saved_context = contextvars.copy_context()
67
-
68
- if (max_concurrency > 0):
69
- self._semaphore = asyncio.Semaphore(max_concurrency)
70
- else:
71
- # If max_concurrency is 0, then we don't need to limit the concurrency but we still need a context
72
- self._semaphore = nullcontext()
73
-
74
- @property
75
- def config(self) -> AIQConfig:
76
- return self._workflow.config
77
-
78
- @property
79
- def workflow(self) -> Workflow:
80
- return self._workflow
81
-
82
- @property
83
- def context(self) -> AIQContext:
84
- return self._context
85
-
86
- @asynccontextmanager
87
- async def session(self,
88
- user_manager=None,
89
- request: Request = None,
90
- user_input_callback: Callable[[InteractionPrompt], Awaitable[HumanResponse]] = None):
91
-
92
- token_user_input = None
93
- if user_input_callback is not None:
94
- token_user_input = self._context_state.user_input_callback.set(user_input_callback)
95
-
96
- token_user_manager = None
97
- if user_manager is not None:
98
- token_user_manager = self._context_state.user_manager.set(user_manager)
99
-
100
- self.set_request_attributes(request)
101
-
102
- try:
103
- yield self
104
- finally:
105
- if token_user_manager is not None:
106
- self._context_state.user_manager.reset(token_user_manager)
107
- if token_user_input is not None:
108
- self._context_state.user_input_callback.reset(token_user_input)
109
-
110
- @asynccontextmanager
111
- async def run(self, message):
112
- """
113
- Start a workflow run
114
- """
115
- async with self._semaphore:
116
- # Apply the saved context
117
- for k, v in self._saved_context.items():
118
- k.set(v)
119
-
120
- async with self._workflow.run(message) as runner:
121
- yield runner
122
-
123
- def set_request_attributes(self, request: Request) -> None:
124
- """
125
- Extracts and sets request attributes from an HTTP request.
126
- If request is None, no attributes are set.
127
- """
128
- if request is None:
129
- return
130
-
131
- self._context.metadata._request.method = request.method
132
- self._context.metadata._request.url_path = request.url.path
133
- self._context.metadata._request.url_port = request.url.port
134
- self._context.metadata._request.url_scheme = request.url.scheme
135
- self._context.metadata._request.headers = request.headers
136
- self._context.metadata._request.query_params = request.query_params
137
- self._context.metadata._request.path_params = request.path_params
138
- self._context.metadata._request.client_host = request.client.host
139
- self._context.metadata._request.client_port = request.client.port
140
- self._context.metadata._request.cookies = request.cookies
@@ -1,131 +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 starlette.datastructures import Headers
17
- from starlette.datastructures import QueryParams
18
-
19
- from aiq.data_models.api_server import Request
20
-
21
-
22
- class RequestAttributes:
23
- """
24
- The RequestAttributes class is responsible for managing user-defined
25
- metadata and attributes. It provides a way to store and
26
- expose user-defined attributes to workflow tools.
27
- """
28
-
29
- def __init__(self) -> None:
30
- self._request: Request = Request()
31
-
32
- @property
33
- def method(self) -> str | None:
34
- """
35
- This property retrieves the HTTP method of the request.
36
- It can be GET, POST, PUT, DELETE, etc.
37
-
38
- Returns:
39
- str | None
40
- """
41
- return self._request.method
42
-
43
- @property
44
- def url_path(self) -> str | None:
45
- """
46
- This property retrieves the path from the URL of the request.
47
-
48
- Returns:
49
- str | None
50
- """
51
- return self._request.url_path
52
-
53
- @property
54
- def url_port(self) -> int | None:
55
- """
56
- This property retrieves the port number from the URL of the request.
57
-
58
- Returns:
59
- int | None
60
- """
61
- return self._request.url_port
62
-
63
- @property
64
- def url_scheme(self) -> str | None:
65
- """
66
- This property retrieves the scheme from the URL of the request.
67
-
68
- Returns:
69
- str | None
70
- """
71
- return self._request.url_scheme
72
-
73
- @property
74
- def headers(self) -> Headers | None:
75
- """
76
- This property retrieves the headers from the request stored in a dictionary-like object.
77
-
78
- Returns:
79
- Headers | None
80
- """
81
- return self._request.headers
82
-
83
- @property
84
- def query_params(self) -> QueryParams | None:
85
- """
86
- This property retrieves the query parameters from the request stored in a dictionary-like object.
87
-
88
- Returns:
89
- QueryParams | None
90
- """
91
- return self._request.query_params
92
-
93
- @property
94
- def path_params(self) -> dict[str, str] | None:
95
- """
96
- This property retrieves the path parameters from the request stored in a dictionary-like object.
97
-
98
- Returns:
99
- dict[str, str] | None
100
- """
101
- return self._request.path_params
102
-
103
- @property
104
- def client_host(self) -> str | None:
105
- """
106
- This property retrieves the clients remote hostname or IP address.
107
-
108
- Returns:
109
- str | None
110
- """
111
- return self._request.client_host
112
-
113
- @property
114
- def client_port(self) -> int | None:
115
- """
116
- This property retrieves the clients remote port number from which the client is connecting to.
117
-
118
- Returns:
119
- int | None
120
- """
121
- return self._request.client_port
122
-
123
- @property
124
- def cookies(self) -> dict[str, str] | None:
125
- """
126
- This property retrieves the cookies from the request stored in a dictionary-like object.
127
-
128
- Returns:
129
- dict[str, str] | None
130
- """
131
- return self._request.cookies
aiq/settings/__init__.py DELETED
File without changes
@@ -1,318 +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 json
17
- import logging
18
- import os
19
- import typing
20
- from collections.abc import Callable
21
- from contextlib import contextmanager
22
- from copy import deepcopy
23
-
24
- from platformdirs import user_config_dir
25
- from pydantic import ConfigDict
26
- from pydantic import Discriminator
27
- from pydantic import Tag
28
- from pydantic import ValidationError
29
- from pydantic import ValidationInfo
30
- from pydantic import ValidatorFunctionWrapHandler
31
- from pydantic import field_validator
32
-
33
- from aiq.cli.type_registry import GlobalTypeRegistry
34
- from aiq.cli.type_registry import RegisteredInfo
35
- from aiq.data_models.common import HashableBaseModel
36
- from aiq.data_models.common import TypedBaseModel
37
- from aiq.data_models.common import TypedBaseModelT
38
- from aiq.data_models.registry_handler import RegistryHandlerBaseConfig
39
-
40
- logger = logging.getLogger(__name__)
41
-
42
-
43
- class Settings(HashableBaseModel):
44
-
45
- model_config = ConfigDict(extra="forbid")
46
-
47
- # Registry Handeler Configuration
48
- channels: dict[str, RegistryHandlerBaseConfig] = {}
49
-
50
- _configuration_directory: typing.ClassVar[str]
51
- _settings_changed_hooks: typing.ClassVar[list[Callable[[], None]]] = []
52
- _settings_changed_hooks_active: bool = True
53
-
54
- @field_validator("channels", mode="wrap")
55
- @classmethod
56
- def validate_components(cls, value: typing.Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo):
57
-
58
- try:
59
- return handler(value)
60
- except ValidationError as err:
61
-
62
- for e in err.errors():
63
- if e['type'] == 'union_tag_invalid' and len(e['loc']) > 0:
64
- requested_type = e['loc'][0]
65
-
66
- if (info.field_name == "channels"):
67
- registered_keys = GlobalTypeRegistry.get().get_registered_registry_handlers()
68
- else:
69
- assert False, f"Unknown field name {info.field_name} in validator"
70
-
71
- # Check and see if the there are multiple full types which match this short type
72
- matching_keys = [k for k in registered_keys if k.local_name == requested_type]
73
-
74
- assert len(matching_keys) != 1, "Exact match should have been found. Contact developers"
75
-
76
- matching_key_names = [x.full_type for x in matching_keys]
77
- registered_key_names = [x.full_type for x in registered_keys]
78
-
79
- if (len(matching_keys) == 0):
80
- # This is a case where the requested type is not found. Show a helpful message about what is
81
- # available
82
- raise ValueError(
83
- f"Requested {info.field_name} type `{requested_type}` not found. "
84
- "Have you ensured the necessary package has been installed with `uv pip install`?"
85
- "\nAvailable {} names:\n - {}".format(info.field_name,
86
- '\n - '.join(registered_key_names))) from err
87
-
88
- # This is a case where the requested type is ambiguous.
89
- raise ValueError(f"Requested {info.field_name} type `{requested_type}` is ambiguous. " +
90
- f"Matched multiple {info.field_name} by their local name: {matching_key_names}. " +
91
- f"Please use the fully qualified {info.field_name} name." +
92
- "\nAvailable {} names:\n - {}".format(info.field_name,
93
- '\n - '.join(registered_key_names))) from err
94
-
95
- raise
96
-
97
- @classmethod
98
- def rebuild_annotations(cls):
99
-
100
- def compute_annotation(cls: type[TypedBaseModelT], registrations: list[RegisteredInfo[TypedBaseModelT]]):
101
-
102
- while (len(registrations) < 2):
103
- registrations.append(RegisteredInfo[TypedBaseModelT](full_type=f"_ignore/{len(registrations)}",
104
- config_type=cls))
105
-
106
- short_names: dict[str, int] = {}
107
- type_list: list[tuple[str, type[TypedBaseModelT]]] = []
108
-
109
- # For all keys in the list, split the key by / and increment the count of the last element
110
- for key in registrations:
111
- short_names[key.local_name] = short_names.get(key.local_name, 0) + 1
112
-
113
- type_list.append((key.full_type, key.config_type))
114
-
115
- # Now loop again and if the short name is unique, then create two entries, for the short and full name
116
- for key in registrations:
117
-
118
- if (short_names[key.local_name] == 1):
119
- type_list.append((key.local_name, key.config_type))
120
-
121
- # pylint: disable=consider-alternative-union-syntax
122
- return typing.Union[tuple(typing.Annotated[x_type, Tag(x_id)] for x_id, x_type in type_list)]
123
-
124
- RegistryHandlerAnnotation = dict[
125
- str,
126
- typing.Annotated[compute_annotation(RegistryHandlerBaseConfig,
127
- GlobalTypeRegistry.get().get_registered_registry_handlers()),
128
- Discriminator(TypedBaseModel.discriminator)]]
129
-
130
- should_rebuild = False
131
-
132
- channels_field = cls.model_fields.get("channels")
133
- if channels_field is not None and channels_field.annotation != RegistryHandlerAnnotation:
134
- channels_field.annotation = RegistryHandlerAnnotation
135
- should_rebuild = True
136
-
137
- if (should_rebuild):
138
- cls.model_rebuild(force=True)
139
-
140
- @property
141
- def channel_names(self) -> list:
142
- return list(self.channels.keys())
143
-
144
- @property
145
- def configuration_directory(self) -> str:
146
- return self._configuration_directory
147
-
148
- @property
149
- def configuration_file(self) -> str:
150
- return os.path.join(self.configuration_directory, "config.json")
151
-
152
- @staticmethod
153
- def from_file():
154
-
155
- configuration_directory = os.getenv("AIQ_CONFIG_DIR", user_config_dir(appname="aiq"))
156
-
157
- if not os.path.exists(configuration_directory):
158
- os.makedirs(configuration_directory, exist_ok=True)
159
-
160
- configuration_file = os.path.join(configuration_directory, "config.json")
161
-
162
- file_path = os.path.join(configuration_directory, "config.json")
163
-
164
- if (not os.path.exists(configuration_file)):
165
- loaded_config = {}
166
- else:
167
- with open(file_path, mode="r", encoding="utf-8") as f:
168
- loaded_config = json.load(f)
169
-
170
- settings = Settings(**loaded_config)
171
- settings.set_configuration_directory(configuration_directory)
172
- return settings
173
-
174
- def set_configuration_directory(self, directory: str, remove: bool = False) -> None:
175
- if (remove):
176
- if os.path.exists(self.configuration_directory):
177
- os.rmdir(self.configuration_directory)
178
- self.__class__._configuration_directory = directory
179
-
180
- def reset_configuration_directory(self, remove: bool = False) -> None:
181
- if (remove):
182
- if os.path.exists(self.configuration_directory):
183
- os.rmdir(self.configuration_directory)
184
- self._configuration_directory = os.getenv("AIQ_CONFIG_DIR", user_config_dir(appname="aiq"))
185
-
186
- def _save_settings(self) -> None:
187
-
188
- if not os.path.exists(self.configuration_directory):
189
- os.mkdir(self.configuration_directory)
190
-
191
- with open(self.configuration_file, mode="w", encoding="utf-8") as f:
192
- f.write(self.model_dump_json(indent=4, by_alias=True, serialize_as_any=True))
193
-
194
- self._settings_changed()
195
-
196
- def update_settings(self, config_obj: "dict | Settings"):
197
- self._update_settings(config_obj)
198
-
199
- def _update_settings(self, config_obj: "dict | Settings"):
200
-
201
- if isinstance(config_obj, Settings):
202
- config_obj = config_obj.model_dump(serialize_as_any=True, by_alias=True)
203
-
204
- self._revalidate(config_dict=config_obj)
205
-
206
- self._save_settings()
207
-
208
- def _revalidate(self, config_dict) -> bool:
209
-
210
- try:
211
- validated_data = self.__class__(**config_dict)
212
-
213
- for field in validated_data.model_fields:
214
- match field:
215
- case "channels":
216
- self.channels = validated_data.channels
217
- case _:
218
- raise ValueError(f"Encountered invalid model field: {field}")
219
-
220
- return True
221
-
222
- except Exception as e:
223
- logger.exception("Unable to validate user settings configuration: %s", e, exc_info=True)
224
- return False
225
-
226
- def print_channel_settings(self, channel_type: str | None = None) -> None:
227
-
228
- import yaml
229
-
230
- remote_channels = self.model_dump(serialize_as_any=True, by_alias=True)
231
-
232
- if (not remote_channels or not remote_channels.get("channels")):
233
- logger.warning("No configured channels to list.")
234
- return
235
-
236
- if (channel_type is not None):
237
- filter_channels = []
238
- for channel, settings in remote_channels.items():
239
- if (settings["type"] != channel_type):
240
- filter_channels.append(channel)
241
- for channel in filter_channels:
242
- del remote_channels[channel]
243
-
244
- if (remote_channels):
245
- logger.info(yaml.dump(remote_channels, allow_unicode=True, default_flow_style=False))
246
-
247
- def override_settings(self, config_file: str) -> "Settings":
248
-
249
- from aiq.utils.io.yaml_tools import yaml_load
250
-
251
- override_settings_dict = yaml_load(config_file)
252
-
253
- settings_dict = self.model_dump()
254
- updated_settings = {**override_settings_dict, **settings_dict}
255
- self._update_settings(config_obj=updated_settings)
256
-
257
- return self
258
-
259
- def _settings_changed(self):
260
-
261
- if (not self._settings_changed_hooks_active):
262
- return
263
-
264
- for hook in self._settings_changed_hooks:
265
- hook()
266
-
267
- @contextmanager
268
- def pause_settings_changed_hooks(self):
269
-
270
- self._settings_changed_hooks_active = False
271
-
272
- try:
273
- yield
274
- finally:
275
- self._settings_changed_hooks_active = True
276
-
277
- # Ensure that the registration changed hooks are called
278
- self._settings_changed()
279
-
280
- def add_settings_changed_hook(self, cb: Callable[[], None]) -> None:
281
-
282
- self._settings_changed_hooks.append(cb)
283
-
284
-
285
- GlobalTypeRegistry.get().add_registration_changed_hook(lambda: Settings.rebuild_annotations())
286
-
287
-
288
- class GlobalSettings:
289
-
290
- _global_settings: Settings | None = None
291
-
292
- @staticmethod
293
- def get() -> Settings:
294
-
295
- if (GlobalSettings._global_settings is None):
296
- from aiq.runtime.loader import PluginTypes
297
- from aiq.runtime.loader import discover_and_register_plugins
298
-
299
- discover_and_register_plugins(PluginTypes.REGISTRY_HANDLER)
300
-
301
- GlobalSettings._global_settings = Settings.from_file()
302
-
303
- return GlobalSettings._global_settings
304
-
305
- @staticmethod
306
- @contextmanager
307
- def push():
308
-
309
- saved = GlobalSettings.get()
310
- settings = deepcopy(saved)
311
-
312
- try:
313
- GlobalSettings._global_settings = settings
314
-
315
- yield settings
316
- finally:
317
- GlobalSettings._global_settings = saved
318
- GlobalSettings._global_settings._settings_changed()
aiq/test/.namespace DELETED
@@ -1 +0,0 @@
1
- Note: This is a python namespace package and this directory should remain empty. Do NOT add a `__init__.py` file or any other files to this directory. This file is also needed to ensure the directory exists in git.
aiq/tool/__init__.py DELETED
File without changes
File without changes