aiqtoolkit 1.1.0a20250429__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 (309) hide show
  1. aiq/agent/__init__.py +0 -0
  2. aiq/agent/base.py +76 -0
  3. aiq/agent/dual_node.py +67 -0
  4. aiq/agent/react_agent/__init__.py +0 -0
  5. aiq/agent/react_agent/agent.py +322 -0
  6. aiq/agent/react_agent/output_parser.py +104 -0
  7. aiq/agent/react_agent/prompt.py +46 -0
  8. aiq/agent/react_agent/register.py +148 -0
  9. aiq/agent/reasoning_agent/__init__.py +0 -0
  10. aiq/agent/reasoning_agent/reasoning_agent.py +224 -0
  11. aiq/agent/register.py +23 -0
  12. aiq/agent/rewoo_agent/__init__.py +0 -0
  13. aiq/agent/rewoo_agent/agent.py +410 -0
  14. aiq/agent/rewoo_agent/prompt.py +108 -0
  15. aiq/agent/rewoo_agent/register.py +158 -0
  16. aiq/agent/tool_calling_agent/__init__.py +0 -0
  17. aiq/agent/tool_calling_agent/agent.py +123 -0
  18. aiq/agent/tool_calling_agent/register.py +105 -0
  19. aiq/builder/__init__.py +0 -0
  20. aiq/builder/builder.py +223 -0
  21. aiq/builder/component_utils.py +303 -0
  22. aiq/builder/context.py +198 -0
  23. aiq/builder/embedder.py +24 -0
  24. aiq/builder/eval_builder.py +116 -0
  25. aiq/builder/evaluator.py +29 -0
  26. aiq/builder/framework_enum.py +24 -0
  27. aiq/builder/front_end.py +73 -0
  28. aiq/builder/function.py +297 -0
  29. aiq/builder/function_base.py +372 -0
  30. aiq/builder/function_info.py +627 -0
  31. aiq/builder/intermediate_step_manager.py +125 -0
  32. aiq/builder/llm.py +25 -0
  33. aiq/builder/retriever.py +25 -0
  34. aiq/builder/user_interaction_manager.py +71 -0
  35. aiq/builder/workflow.py +134 -0
  36. aiq/builder/workflow_builder.py +733 -0
  37. aiq/cli/__init__.py +14 -0
  38. aiq/cli/cli_utils/__init__.py +0 -0
  39. aiq/cli/cli_utils/config_override.py +233 -0
  40. aiq/cli/cli_utils/validation.py +37 -0
  41. aiq/cli/commands/__init__.py +0 -0
  42. aiq/cli/commands/configure/__init__.py +0 -0
  43. aiq/cli/commands/configure/channel/__init__.py +0 -0
  44. aiq/cli/commands/configure/channel/add.py +28 -0
  45. aiq/cli/commands/configure/channel/channel.py +34 -0
  46. aiq/cli/commands/configure/channel/remove.py +30 -0
  47. aiq/cli/commands/configure/channel/update.py +30 -0
  48. aiq/cli/commands/configure/configure.py +33 -0
  49. aiq/cli/commands/evaluate.py +139 -0
  50. aiq/cli/commands/info/__init__.py +14 -0
  51. aiq/cli/commands/info/info.py +37 -0
  52. aiq/cli/commands/info/list_channels.py +32 -0
  53. aiq/cli/commands/info/list_components.py +129 -0
  54. aiq/cli/commands/registry/__init__.py +14 -0
  55. aiq/cli/commands/registry/publish.py +88 -0
  56. aiq/cli/commands/registry/pull.py +118 -0
  57. aiq/cli/commands/registry/registry.py +36 -0
  58. aiq/cli/commands/registry/remove.py +108 -0
  59. aiq/cli/commands/registry/search.py +155 -0
  60. aiq/cli/commands/start.py +250 -0
  61. aiq/cli/commands/uninstall.py +83 -0
  62. aiq/cli/commands/validate.py +47 -0
  63. aiq/cli/commands/workflow/__init__.py +14 -0
  64. aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
  65. aiq/cli/commands/workflow/templates/config.yml.j2 +16 -0
  66. aiq/cli/commands/workflow/templates/pyproject.toml.j2 +22 -0
  67. aiq/cli/commands/workflow/templates/register.py.j2 +5 -0
  68. aiq/cli/commands/workflow/templates/workflow.py.j2 +36 -0
  69. aiq/cli/commands/workflow/workflow.py +37 -0
  70. aiq/cli/commands/workflow/workflow_commands.py +307 -0
  71. aiq/cli/entrypoint.py +133 -0
  72. aiq/cli/main.py +44 -0
  73. aiq/cli/register_workflow.py +408 -0
  74. aiq/cli/type_registry.py +869 -0
  75. aiq/data_models/__init__.py +14 -0
  76. aiq/data_models/api_server.py +550 -0
  77. aiq/data_models/common.py +143 -0
  78. aiq/data_models/component.py +46 -0
  79. aiq/data_models/component_ref.py +135 -0
  80. aiq/data_models/config.py +349 -0
  81. aiq/data_models/dataset_handler.py +122 -0
  82. aiq/data_models/discovery_metadata.py +269 -0
  83. aiq/data_models/embedder.py +26 -0
  84. aiq/data_models/evaluate.py +101 -0
  85. aiq/data_models/evaluator.py +26 -0
  86. aiq/data_models/front_end.py +26 -0
  87. aiq/data_models/function.py +30 -0
  88. aiq/data_models/function_dependencies.py +64 -0
  89. aiq/data_models/interactive.py +237 -0
  90. aiq/data_models/intermediate_step.py +269 -0
  91. aiq/data_models/invocation_node.py +38 -0
  92. aiq/data_models/llm.py +26 -0
  93. aiq/data_models/logging.py +26 -0
  94. aiq/data_models/memory.py +26 -0
  95. aiq/data_models/profiler.py +53 -0
  96. aiq/data_models/registry_handler.py +26 -0
  97. aiq/data_models/retriever.py +30 -0
  98. aiq/data_models/step_adaptor.py +64 -0
  99. aiq/data_models/streaming.py +33 -0
  100. aiq/data_models/swe_bench_model.py +54 -0
  101. aiq/data_models/telemetry_exporter.py +26 -0
  102. aiq/embedder/__init__.py +0 -0
  103. aiq/embedder/langchain_client.py +41 -0
  104. aiq/embedder/nim_embedder.py +58 -0
  105. aiq/embedder/openai_embedder.py +42 -0
  106. aiq/embedder/register.py +24 -0
  107. aiq/eval/__init__.py +14 -0
  108. aiq/eval/config.py +42 -0
  109. aiq/eval/dataset_handler/__init__.py +0 -0
  110. aiq/eval/dataset_handler/dataset_downloader.py +106 -0
  111. aiq/eval/dataset_handler/dataset_filter.py +52 -0
  112. aiq/eval/dataset_handler/dataset_handler.py +164 -0
  113. aiq/eval/evaluate.py +322 -0
  114. aiq/eval/evaluator/__init__.py +14 -0
  115. aiq/eval/evaluator/evaluator_model.py +44 -0
  116. aiq/eval/intermediate_step_adapter.py +93 -0
  117. aiq/eval/rag_evaluator/__init__.py +0 -0
  118. aiq/eval/rag_evaluator/evaluate.py +138 -0
  119. aiq/eval/rag_evaluator/register.py +138 -0
  120. aiq/eval/register.py +22 -0
  121. aiq/eval/remote_workflow.py +128 -0
  122. aiq/eval/runtime_event_subscriber.py +52 -0
  123. aiq/eval/swe_bench_evaluator/__init__.py +0 -0
  124. aiq/eval/swe_bench_evaluator/evaluate.py +215 -0
  125. aiq/eval/swe_bench_evaluator/register.py +36 -0
  126. aiq/eval/trajectory_evaluator/__init__.py +0 -0
  127. aiq/eval/trajectory_evaluator/evaluate.py +118 -0
  128. aiq/eval/trajectory_evaluator/register.py +40 -0
  129. aiq/eval/utils/__init__.py +0 -0
  130. aiq/eval/utils/output_uploader.py +131 -0
  131. aiq/eval/utils/tqdm_position_registry.py +40 -0
  132. aiq/front_ends/__init__.py +14 -0
  133. aiq/front_ends/console/__init__.py +14 -0
  134. aiq/front_ends/console/console_front_end_config.py +32 -0
  135. aiq/front_ends/console/console_front_end_plugin.py +107 -0
  136. aiq/front_ends/console/register.py +25 -0
  137. aiq/front_ends/cron/__init__.py +14 -0
  138. aiq/front_ends/fastapi/__init__.py +14 -0
  139. aiq/front_ends/fastapi/fastapi_front_end_config.py +150 -0
  140. aiq/front_ends/fastapi/fastapi_front_end_plugin.py +103 -0
  141. aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +574 -0
  142. aiq/front_ends/fastapi/intermediate_steps_subscriber.py +80 -0
  143. aiq/front_ends/fastapi/job_store.py +161 -0
  144. aiq/front_ends/fastapi/main.py +70 -0
  145. aiq/front_ends/fastapi/message_handler.py +279 -0
  146. aiq/front_ends/fastapi/message_validator.py +345 -0
  147. aiq/front_ends/fastapi/register.py +25 -0
  148. aiq/front_ends/fastapi/response_helpers.py +181 -0
  149. aiq/front_ends/fastapi/step_adaptor.py +315 -0
  150. aiq/front_ends/fastapi/websocket.py +148 -0
  151. aiq/front_ends/mcp/__init__.py +14 -0
  152. aiq/front_ends/mcp/mcp_front_end_config.py +32 -0
  153. aiq/front_ends/mcp/mcp_front_end_plugin.py +93 -0
  154. aiq/front_ends/mcp/register.py +27 -0
  155. aiq/front_ends/mcp/tool_converter.py +242 -0
  156. aiq/front_ends/register.py +22 -0
  157. aiq/front_ends/simple_base/__init__.py +14 -0
  158. aiq/front_ends/simple_base/simple_front_end_plugin_base.py +52 -0
  159. aiq/llm/__init__.py +0 -0
  160. aiq/llm/nim_llm.py +45 -0
  161. aiq/llm/openai_llm.py +45 -0
  162. aiq/llm/register.py +22 -0
  163. aiq/llm/utils/__init__.py +14 -0
  164. aiq/llm/utils/env_config_value.py +94 -0
  165. aiq/llm/utils/error.py +17 -0
  166. aiq/memory/__init__.py +20 -0
  167. aiq/memory/interfaces.py +183 -0
  168. aiq/memory/models.py +102 -0
  169. aiq/meta/module_to_distro.json +3 -0
  170. aiq/meta/pypi.md +59 -0
  171. aiq/observability/__init__.py +0 -0
  172. aiq/observability/async_otel_listener.py +270 -0
  173. aiq/observability/register.py +97 -0
  174. aiq/plugins/.namespace +1 -0
  175. aiq/profiler/__init__.py +0 -0
  176. aiq/profiler/callbacks/__init__.py +0 -0
  177. aiq/profiler/callbacks/agno_callback_handler.py +295 -0
  178. aiq/profiler/callbacks/base_callback_class.py +20 -0
  179. aiq/profiler/callbacks/langchain_callback_handler.py +278 -0
  180. aiq/profiler/callbacks/llama_index_callback_handler.py +205 -0
  181. aiq/profiler/callbacks/semantic_kernel_callback_handler.py +238 -0
  182. aiq/profiler/callbacks/token_usage_base_model.py +27 -0
  183. aiq/profiler/data_frame_row.py +51 -0
  184. aiq/profiler/decorators/__init__.py +0 -0
  185. aiq/profiler/decorators/framework_wrapper.py +131 -0
  186. aiq/profiler/decorators/function_tracking.py +254 -0
  187. aiq/profiler/forecasting/__init__.py +0 -0
  188. aiq/profiler/forecasting/config.py +18 -0
  189. aiq/profiler/forecasting/model_trainer.py +75 -0
  190. aiq/profiler/forecasting/models/__init__.py +22 -0
  191. aiq/profiler/forecasting/models/forecasting_base_model.py +40 -0
  192. aiq/profiler/forecasting/models/linear_model.py +196 -0
  193. aiq/profiler/forecasting/models/random_forest_regressor.py +268 -0
  194. aiq/profiler/inference_metrics_model.py +25 -0
  195. aiq/profiler/inference_optimization/__init__.py +0 -0
  196. aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
  197. aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +452 -0
  198. aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +258 -0
  199. aiq/profiler/inference_optimization/data_models.py +386 -0
  200. aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
  201. aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +468 -0
  202. aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +405 -0
  203. aiq/profiler/inference_optimization/llm_metrics.py +212 -0
  204. aiq/profiler/inference_optimization/prompt_caching.py +163 -0
  205. aiq/profiler/inference_optimization/token_uniqueness.py +107 -0
  206. aiq/profiler/inference_optimization/workflow_runtimes.py +72 -0
  207. aiq/profiler/intermediate_property_adapter.py +102 -0
  208. aiq/profiler/profile_runner.py +433 -0
  209. aiq/profiler/utils.py +184 -0
  210. aiq/registry_handlers/__init__.py +0 -0
  211. aiq/registry_handlers/local/__init__.py +0 -0
  212. aiq/registry_handlers/local/local_handler.py +176 -0
  213. aiq/registry_handlers/local/register_local.py +37 -0
  214. aiq/registry_handlers/metadata_factory.py +60 -0
  215. aiq/registry_handlers/package_utils.py +198 -0
  216. aiq/registry_handlers/pypi/__init__.py +0 -0
  217. aiq/registry_handlers/pypi/pypi_handler.py +251 -0
  218. aiq/registry_handlers/pypi/register_pypi.py +40 -0
  219. aiq/registry_handlers/register.py +21 -0
  220. aiq/registry_handlers/registry_handler_base.py +157 -0
  221. aiq/registry_handlers/rest/__init__.py +0 -0
  222. aiq/registry_handlers/rest/register_rest.py +56 -0
  223. aiq/registry_handlers/rest/rest_handler.py +237 -0
  224. aiq/registry_handlers/schemas/__init__.py +0 -0
  225. aiq/registry_handlers/schemas/headers.py +42 -0
  226. aiq/registry_handlers/schemas/package.py +68 -0
  227. aiq/registry_handlers/schemas/publish.py +63 -0
  228. aiq/registry_handlers/schemas/pull.py +81 -0
  229. aiq/registry_handlers/schemas/remove.py +36 -0
  230. aiq/registry_handlers/schemas/search.py +91 -0
  231. aiq/registry_handlers/schemas/status.py +47 -0
  232. aiq/retriever/__init__.py +0 -0
  233. aiq/retriever/interface.py +37 -0
  234. aiq/retriever/milvus/__init__.py +14 -0
  235. aiq/retriever/milvus/register.py +81 -0
  236. aiq/retriever/milvus/retriever.py +228 -0
  237. aiq/retriever/models.py +74 -0
  238. aiq/retriever/nemo_retriever/__init__.py +14 -0
  239. aiq/retriever/nemo_retriever/register.py +60 -0
  240. aiq/retriever/nemo_retriever/retriever.py +190 -0
  241. aiq/retriever/register.py +22 -0
  242. aiq/runtime/__init__.py +14 -0
  243. aiq/runtime/loader.py +188 -0
  244. aiq/runtime/runner.py +176 -0
  245. aiq/runtime/session.py +116 -0
  246. aiq/settings/__init__.py +0 -0
  247. aiq/settings/global_settings.py +318 -0
  248. aiq/test/.namespace +1 -0
  249. aiq/tool/__init__.py +0 -0
  250. aiq/tool/code_execution/__init__.py +0 -0
  251. aiq/tool/code_execution/code_sandbox.py +188 -0
  252. aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +60 -0
  253. aiq/tool/code_execution/local_sandbox/__init__.py +13 -0
  254. aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +79 -0
  255. aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +4 -0
  256. aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +25 -0
  257. aiq/tool/code_execution/register.py +70 -0
  258. aiq/tool/code_execution/utils.py +100 -0
  259. aiq/tool/datetime_tools.py +42 -0
  260. aiq/tool/document_search.py +141 -0
  261. aiq/tool/github_tools/__init__.py +0 -0
  262. aiq/tool/github_tools/create_github_commit.py +133 -0
  263. aiq/tool/github_tools/create_github_issue.py +87 -0
  264. aiq/tool/github_tools/create_github_pr.py +106 -0
  265. aiq/tool/github_tools/get_github_file.py +106 -0
  266. aiq/tool/github_tools/get_github_issue.py +166 -0
  267. aiq/tool/github_tools/get_github_pr.py +256 -0
  268. aiq/tool/github_tools/update_github_issue.py +100 -0
  269. aiq/tool/mcp/__init__.py +14 -0
  270. aiq/tool/mcp/mcp_client.py +220 -0
  271. aiq/tool/mcp/mcp_tool.py +75 -0
  272. aiq/tool/memory_tools/__init__.py +0 -0
  273. aiq/tool/memory_tools/add_memory_tool.py +67 -0
  274. aiq/tool/memory_tools/delete_memory_tool.py +67 -0
  275. aiq/tool/memory_tools/get_memory_tool.py +72 -0
  276. aiq/tool/nvidia_rag.py +95 -0
  277. aiq/tool/register.py +36 -0
  278. aiq/tool/retriever.py +89 -0
  279. aiq/utils/__init__.py +0 -0
  280. aiq/utils/data_models/__init__.py +0 -0
  281. aiq/utils/data_models/schema_validator.py +58 -0
  282. aiq/utils/debugging_utils.py +43 -0
  283. aiq/utils/exception_handlers/__init__.py +0 -0
  284. aiq/utils/exception_handlers/schemas.py +114 -0
  285. aiq/utils/io/__init__.py +0 -0
  286. aiq/utils/io/yaml_tools.py +50 -0
  287. aiq/utils/metadata_utils.py +74 -0
  288. aiq/utils/producer_consumer_queue.py +178 -0
  289. aiq/utils/reactive/__init__.py +0 -0
  290. aiq/utils/reactive/base/__init__.py +0 -0
  291. aiq/utils/reactive/base/observable_base.py +65 -0
  292. aiq/utils/reactive/base/observer_base.py +55 -0
  293. aiq/utils/reactive/base/subject_base.py +79 -0
  294. aiq/utils/reactive/observable.py +59 -0
  295. aiq/utils/reactive/observer.py +76 -0
  296. aiq/utils/reactive/subject.py +131 -0
  297. aiq/utils/reactive/subscription.py +49 -0
  298. aiq/utils/settings/__init__.py +0 -0
  299. aiq/utils/settings/global_settings.py +197 -0
  300. aiq/utils/type_converter.py +232 -0
  301. aiq/utils/type_utils.py +397 -0
  302. aiq/utils/url_utils.py +27 -0
  303. aiqtoolkit-1.1.0a20250429.dist-info/METADATA +326 -0
  304. aiqtoolkit-1.1.0a20250429.dist-info/RECORD +309 -0
  305. aiqtoolkit-1.1.0a20250429.dist-info/WHEEL +5 -0
  306. aiqtoolkit-1.1.0a20250429.dist-info/entry_points.txt +17 -0
  307. aiqtoolkit-1.1.0a20250429.dist-info/licenses/LICENSE-3rd-party.txt +3686 -0
  308. aiqtoolkit-1.1.0a20250429.dist-info/licenses/LICENSE.md +201 -0
  309. aiqtoolkit-1.1.0a20250429.dist-info/top_level.txt +1 -0
@@ -0,0 +1,269 @@
1
+ # SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ import importlib.metadata
17
+ import inspect
18
+ import json
19
+ import logging
20
+ import typing
21
+ from enum import Enum
22
+ from functools import lru_cache
23
+ from pathlib import Path
24
+ from typing import TYPE_CHECKING
25
+
26
+ from pydantic import BaseModel
27
+ from pydantic import field_validator
28
+
29
+ from aiq.builder.framework_enum import LLMFrameworkEnum
30
+ from aiq.data_models.component import AIQComponentEnum
31
+ from aiq.utils.metadata_utils import generate_config_type_docs
32
+
33
+ if TYPE_CHECKING:
34
+ from aiq.cli.type_registry import ToolWrapperBuildCallableT
35
+ from aiq.data_models.common import TypedBaseModelT
36
+
37
+ logger = logging.getLogger(__name__)
38
+
39
+
40
+ class DiscoveryStatusEnum(str, Enum):
41
+ SUCCESS = "success"
42
+ FAILURE = "failure"
43
+
44
+
45
+ class DiscoveryContractFieldsEnum(str, Enum):
46
+ PACKAGE = "package"
47
+ VERSION = "version"
48
+ COMPONENT_TYPE = "component_type"
49
+ COMPONENT_NAME = "component_name"
50
+ DESCRIPTION = "description"
51
+ DEVELOPER_NOTES = "developer_notes"
52
+
53
+
54
+ class DiscoveryMetadata(BaseModel):
55
+ """A data model representing metadata about each registered component to faciliate its discovery.
56
+
57
+ Args:
58
+ package (str): The name of the package containing the AgentIQ component.
59
+ version (str): The version number of the package containing the AgentIQ component.
60
+ component_type (AIQComponentEnum): The type of AgentIQ component this metadata represents.
61
+ component_name (str): The registered name of the AgentIQ component.
62
+ description (str): Description of the AgentIQ component pulled from its config objects docstrings.
63
+ developer_notes (str): Other notes to a developers to aid in the use of the component.
64
+ status (DiscoveryStatusEnum): Provides the status of the metadata discovery process.
65
+ """
66
+
67
+ package: str = ""
68
+ version: str = ""
69
+ component_type: AIQComponentEnum = AIQComponentEnum.UNDEFINED
70
+ component_name: str = ""
71
+ description: str = ""
72
+ developer_notes: str = ""
73
+ status: DiscoveryStatusEnum = DiscoveryStatusEnum.SUCCESS
74
+
75
+ @field_validator("description", mode="before")
76
+ @classmethod
77
+ def ensure_description_string(cls, v: typing.Any):
78
+ if not isinstance(v, str):
79
+ return ""
80
+ return v
81
+
82
+ @staticmethod
83
+ def get_preferred_item(items: list, preferred: str) -> str:
84
+ return preferred if preferred in items else items[0]
85
+
86
+ @staticmethod
87
+ @lru_cache
88
+ def get_distribution_name_from_metadata(root_package_name: str) -> str | None:
89
+ """
90
+ This is not performant and is only present to be used (not used
91
+ currently) as a fallback when the distro name doesn't match the
92
+ module name and private_data is not available to map it.
93
+ """
94
+ mapping = importlib.metadata.packages_distributions()
95
+ try:
96
+ distro_names = mapping.get(root_package_name, [None])
97
+ distro_name = DiscoveryMetadata.get_preferred_item(distro_names, "aiqtoolkit")
98
+ except KeyError:
99
+ return root_package_name
100
+
101
+ return distro_name if distro_name else root_package_name
102
+
103
+ @staticmethod
104
+ @lru_cache
105
+ def get_distribution_name_from_private_data(root_package: str) -> str | None:
106
+ # Locate distibution mapping stored in the packages private data
107
+ module = __import__(root_package)
108
+ for path in module.__path__:
109
+ package_dir = Path(path).resolve()
110
+ distinfo_path = package_dir / "meta" / "module_to_distro.json"
111
+
112
+ if distinfo_path.exists():
113
+ with distinfo_path.open("r") as f:
114
+ data = json.load(f)
115
+ return data.get(root_package, None)
116
+ return None
117
+
118
+ @staticmethod
119
+ @lru_cache
120
+ def get_distribution_name(root_package: str) -> str:
121
+ """
122
+ The aiq library packages use a distro name 'aiqtoolkit[]' and
123
+ root package name 'aiq'. They provide mapping in a metadata file
124
+ for optimized installation.
125
+ """
126
+ distro_name = DiscoveryMetadata.get_distribution_name_from_private_data(root_package)
127
+ return distro_name if distro_name else root_package
128
+
129
+ @staticmethod
130
+ def from_config_type(config_type: type["TypedBaseModelT"],
131
+ component_type: AIQComponentEnum = AIQComponentEnum.UNDEFINED) -> "DiscoveryMetadata":
132
+ """Generates discovery metadata from an AgentIQ config object.
133
+
134
+ Args:
135
+ config_type (type[TypedBaseModelT]): A registered component's configuration object.
136
+ component_type (AIQComponentEnum, optional): The type of the registered component. Defaults to
137
+ AIQComponentEnum.UNDEFINED.
138
+
139
+ Returns:
140
+ DiscoveryMetadata: A an object containing component metadata to facilitate discovery and reuse.
141
+ """
142
+
143
+ try:
144
+ module = inspect.getmodule(config_type)
145
+ root_package: str = module.__package__.split(".")[0]
146
+ distro_name = DiscoveryMetadata.get_distribution_name(root_package)
147
+
148
+ if not distro_name:
149
+ # raise an exception
150
+ logger.error("Encountered issue getting distro_name for module %s", module.__name__)
151
+ return DiscoveryMetadata(status=DiscoveryStatusEnum.FAILURE)
152
+
153
+ version = importlib.metadata.version(distro_name) if distro_name != "" else ""
154
+ except Exception as e:
155
+ logger.exception("Encountered issue extracting module metadata for %s: %s", config_type, e, exc_info=True)
156
+ return DiscoveryMetadata(status=DiscoveryStatusEnum.FAILURE)
157
+
158
+ description = generate_config_type_docs(config_type=config_type)
159
+
160
+ return DiscoveryMetadata(package=distro_name,
161
+ version=version,
162
+ component_type=component_type,
163
+ component_name=config_type.static_type(),
164
+ description=description)
165
+
166
+ @staticmethod
167
+ def from_fn_wrapper(fn: "ToolWrapperBuildCallableT",
168
+ wrapper_type: LLMFrameworkEnum | str,
169
+ component_type: AIQComponentEnum = AIQComponentEnum.TOOL_WRAPPER) -> "DiscoveryMetadata":
170
+ """Generates discovery metadata from function with specified wrapper type.
171
+
172
+ Args:
173
+ fn (ToolWrapperBuildCallableT): A tool wrapper callable to source component metadata.
174
+ wrapper_type (LLMFrameworkEnum): The wrapper to apply to the callable to faciliate inter-framwork
175
+ interoperability.
176
+
177
+ component_type (AIQComponentEnum, optional): The type of the registered component. Defaults to
178
+ AIQComponentEnum.TOOL_WRAPPER.
179
+
180
+ Returns:
181
+ DiscoveryMetadata: A an object containing component metadata to facilitate discovery and reuse.
182
+ """
183
+
184
+ try:
185
+ module = inspect.getmodule(fn)
186
+ root_package: str = module.__package__.split(".")[0]
187
+ root_package = DiscoveryMetadata.get_distribution_name(root_package)
188
+ version = importlib.metadata.version(root_package) if root_package != "" else ""
189
+ except Exception as e:
190
+ logger.exception("Encountered issue extracting module metadata for %s: %s", fn, e, exc_info=True)
191
+ return DiscoveryMetadata(status=DiscoveryStatusEnum.FAILURE)
192
+
193
+ if isinstance(wrapper_type, LLMFrameworkEnum):
194
+ wrapper_type = wrapper_type.value
195
+
196
+ return DiscoveryMetadata(package=root_package,
197
+ version=version,
198
+ component_type=component_type,
199
+ component_name=wrapper_type,
200
+ description=fn.__doc__ or "")
201
+
202
+ @staticmethod
203
+ def from_package_name(package_name: str, package_version: str | None) -> "DiscoveryMetadata":
204
+ """Generates discovery metadata from an installed package name.
205
+
206
+ Args:
207
+ package_name (str): The name of the AgentIQ plugin package containing registered components.
208
+ package_version (str, optional): The version of the package, Defaults to None.
209
+
210
+ Returns:
211
+ DiscoveryMetadata: A an object containing component metadata to facilitate discovery and reuse.
212
+ """
213
+
214
+ try:
215
+ package_name = DiscoveryMetadata.get_distribution_name(package_name)
216
+ metadata = importlib.metadata.metadata(package_name)
217
+ description = metadata.get("Summary", "")
218
+ if (package_version is None):
219
+ package_version = importlib.metadata.version(package_name)
220
+ except Exception as e:
221
+ logger.exception("Encountered issue extracting module metadata for %s: %s", package_name, e, exc_info=True)
222
+ return DiscoveryMetadata(status=DiscoveryStatusEnum.FAILURE)
223
+
224
+ return DiscoveryMetadata(package=package_name,
225
+ version=package_version,
226
+ component_type=AIQComponentEnum.PACKAGE,
227
+ component_name=package_name,
228
+ description=description)
229
+
230
+ @staticmethod
231
+ def from_provider_framework_map(
232
+ config_type: type["TypedBaseModelT"],
233
+ wrapper_type: LLMFrameworkEnum | str | None,
234
+ provider_type: AIQComponentEnum,
235
+ component_type: AIQComponentEnum = AIQComponentEnum.UNDEFINED) -> "DiscoveryMetadata":
236
+ """Generates discovery metadata from provider and framework mapping information.
237
+
238
+ Args:
239
+ config_type (type[TypedBaseModelT]): A registered component's configuration object.
240
+ wrapper_type (LLMFrameworkEnum | str): The wrapper to apply to the callable to faciliate inter-framwork
241
+ interoperability.
242
+
243
+ provider_type (AIQComponentEnum): The type of provider the registered component supports.
244
+ component_type (AIQComponentEnum, optional): The type of the registered component. Defaults to
245
+ AIQComponentEnum.UNDEFINED.
246
+
247
+ Returns:
248
+ DiscoveryMetadata: A an object containing component metadata to facilitate discovery and reuse.
249
+ """
250
+
251
+ try:
252
+ module = inspect.getmodule(config_type)
253
+ root_package: str = module.__package__.split(".")[0]
254
+ root_package = DiscoveryMetadata.get_distribution_name(root_package)
255
+ version = importlib.metadata.version(root_package) if root_package != "" else ""
256
+ except Exception as e:
257
+ logger.exception("Encountered issue extracting module metadata for %s: %s", config_type, e, exc_info=True)
258
+ return DiscoveryMetadata(status=DiscoveryStatusEnum.FAILURE)
259
+
260
+ wrapper_type = wrapper_type.value if isinstance(wrapper_type, LLMFrameworkEnum) else wrapper_type
261
+ component_name = f"{config_type.static_type()} ({provider_type.value}) - {wrapper_type}"
262
+
263
+ description = generate_config_type_docs(config_type=config_type)
264
+
265
+ return DiscoveryMetadata(package=root_package,
266
+ version=version,
267
+ component_type=component_type,
268
+ component_name=component_name,
269
+ description=description)
@@ -0,0 +1,26 @@
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 typing
17
+
18
+ from .common import BaseModelRegistryTag
19
+ from .common import TypedBaseModel
20
+
21
+
22
+ class EmbedderBaseConfig(TypedBaseModel, BaseModelRegistryTag):
23
+ pass
24
+
25
+
26
+ EmbedderBaseConfigT = typing.TypeVar("EmbedderBaseConfigT", bound=EmbedderBaseConfig)
@@ -0,0 +1,101 @@
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 typing
17
+ from pathlib import Path
18
+
19
+ from pydantic import BaseModel
20
+ from pydantic import Discriminator
21
+ from pydantic import model_validator
22
+
23
+ from aiq.data_models.common import TypedBaseModel
24
+ from aiq.data_models.dataset_handler import EvalDatasetConfig
25
+ from aiq.data_models.dataset_handler import EvalS3Config
26
+ from aiq.data_models.evaluator import EvaluatorBaseConfig
27
+ from aiq.data_models.profiler import ProfilerConfig
28
+
29
+
30
+ class EvalCustomScriptConfig(BaseModel):
31
+ # Path to the script to run
32
+ script: Path
33
+ # Keyword arguments to pass to the script
34
+ kwargs: dict[str, str] = {}
35
+
36
+
37
+ class EvalOutputConfig(BaseModel):
38
+ # Output directory for the workflow and evaluation results
39
+ dir: Path = Path("/tmp/aiq/examples/default/")
40
+ # S3 prefix for the workflow and evaluation results
41
+ remote_dir: str | None = None
42
+ # Custom scripts to run after the workflow and evaluation results are saved
43
+ custom_scripts: dict[str, EvalCustomScriptConfig] = {}
44
+ # S3 config for uploading the contents of the output directory
45
+ s3: EvalS3Config | None = None
46
+ # Whether to cleanup the output directory before running the workflow
47
+ cleanup: bool = True
48
+
49
+
50
+ class EvalGeneralConfig(BaseModel):
51
+ max_concurrency: int = 8
52
+
53
+ # Output directory for the workflow and evaluation results
54
+ output_dir: Path = Path("/tmp/aiq/examples/default/")
55
+
56
+ # If present overrides output_dir
57
+ output: EvalOutputConfig | None = None
58
+
59
+ # Dataset for running the workflow and evaluating
60
+ dataset: EvalDatasetConfig | None = None
61
+
62
+ # Inference profiler
63
+ profiler: ProfilerConfig | None = None
64
+
65
+ # overwrite the output_dir with the output config if present
66
+ @model_validator(mode="before")
67
+ @classmethod
68
+ def override_output_dir(cls, values):
69
+ if values.get("output") and values["output"].get("dir"):
70
+ values["output_dir"] = values["output"]["dir"]
71
+ return values
72
+
73
+
74
+ class EvalConfig(BaseModel):
75
+
76
+ # General Evaluation Options
77
+ general: EvalGeneralConfig = EvalGeneralConfig()
78
+
79
+ # Evaluators
80
+ evaluators: dict[str, EvaluatorBaseConfig] = {}
81
+
82
+ @classmethod
83
+ def rebuild_annotations(cls):
84
+
85
+ from aiq.cli.type_registry import GlobalTypeRegistry # pylint: disable=cyclic-import
86
+
87
+ type_registry = GlobalTypeRegistry.get()
88
+
89
+ EvaluatorsAnnotation = dict[str,
90
+ typing.Annotated[type_registry.compute_annotation(EvaluatorBaseConfig),
91
+ Discriminator(TypedBaseModel.discriminator)]]
92
+
93
+ should_rebuild = False
94
+
95
+ evaluators_field = cls.model_fields.get("evaluators")
96
+ if evaluators_field is not None and evaluators_field.annotation != EvaluatorsAnnotation:
97
+ evaluators_field.annotation = EvaluatorsAnnotation
98
+ should_rebuild = True
99
+
100
+ if (should_rebuild):
101
+ cls.model_rebuild(force=True)
@@ -0,0 +1,26 @@
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 typing
17
+
18
+ from .common import BaseModelRegistryTag
19
+ from .common import TypedBaseModel
20
+
21
+
22
+ class EvaluatorBaseConfig(TypedBaseModel, BaseModelRegistryTag):
23
+ pass
24
+
25
+
26
+ EvaluatorBaseConfigT = typing.TypeVar("EvaluatorBaseConfigT", bound=EvaluatorBaseConfig)
@@ -0,0 +1,26 @@
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 typing
17
+
18
+ from .common import BaseModelRegistryTag
19
+ from .common import TypedBaseModel
20
+
21
+
22
+ class FrontEndBaseConfig(TypedBaseModel, BaseModelRegistryTag):
23
+ pass
24
+
25
+
26
+ FrontEndConfigT = typing.TypeVar("FrontEndConfigT", bound=FrontEndBaseConfig)
@@ -0,0 +1,30 @@
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 typing
17
+
18
+ from .common import BaseModelRegistryTag
19
+ from .common import TypedBaseModel
20
+
21
+
22
+ class FunctionBaseConfig(TypedBaseModel, BaseModelRegistryTag):
23
+ pass
24
+
25
+
26
+ class EmptyFunctionConfig(FunctionBaseConfig, name="EmptyFunctionConfig"):
27
+ pass
28
+
29
+
30
+ FunctionConfigT = typing.TypeVar("FunctionConfigT", bound=FunctionBaseConfig)
@@ -0,0 +1,64 @@
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 pydantic import BaseModel
17
+ from pydantic import Field
18
+ from pydantic import field_serializer
19
+
20
+
21
+ class FunctionDependencies(BaseModel):
22
+ """
23
+ A class to represent the dependencies of a function.
24
+ """
25
+ functions: set[str] = Field(default_factory=set)
26
+ llms: set[str] = Field(default_factory=set)
27
+ embedders: set[str] = Field(default_factory=set)
28
+ memory_clients: set[str] = Field(default_factory=set)
29
+ retrievers: set[str] = Field(default_factory=set)
30
+
31
+ @field_serializer("functions", when_used="json")
32
+ def serialize_functions(self, v: set[str]) -> list[str]:
33
+ return list(v)
34
+
35
+ @field_serializer("llms", when_used="json")
36
+ def serialize_llms(self, v: set[str]) -> list[str]:
37
+ return list(v)
38
+
39
+ @field_serializer("embedders", when_used="json")
40
+ def serialize_embedders(self, v: set[str]) -> list[str]:
41
+ return list(v)
42
+
43
+ @field_serializer("memory_clients", when_used="json")
44
+ def serialize_memory_clients(self, v: set[str]) -> list[str]:
45
+ return list(v)
46
+
47
+ @field_serializer("retrievers", when_used="json")
48
+ def serialize_retrievers(self, v: set[str]) -> list[str]:
49
+ return list(v)
50
+
51
+ def add_function(self, function: str):
52
+ self.functions.add(function) # pylint: disable=no-member
53
+
54
+ def add_llm(self, llm: str):
55
+ self.llms.add(llm) # pylint: disable=no-member
56
+
57
+ def add_embedder(self, embedder: str):
58
+ self.embedders.add(embedder) # pylint: disable=no-member
59
+
60
+ def add_memory_client(self, memory_client: str):
61
+ self.memory_clients.add(memory_client) # pylint: disable=no-member
62
+
63
+ def add_retriever(self, retriever: str):
64
+ self.retrievers.add(retriever) # pylint: disable=no-member