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
@@ -1,254 +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 functools
17
- import inspect
18
- import uuid
19
- from typing import Any
20
-
21
- from pydantic import BaseModel
22
-
23
- from aiq.builder.context import AIQContext
24
- from aiq.builder.intermediate_step_manager import IntermediateStepManager
25
- from aiq.data_models.intermediate_step import IntermediateStepPayload
26
- from aiq.data_models.intermediate_step import IntermediateStepType
27
- from aiq.data_models.intermediate_step import TraceMetadata
28
-
29
-
30
- # --- Helper function to recursively serialize any object into JSON-friendly data ---
31
- def _serialize_data(obj: Any) -> Any:
32
- """Convert `obj` into a structure that can be passed to `json.dumps(...)`."""
33
- if isinstance(obj, BaseModel):
34
- # Convert Pydantic model to dict
35
- return obj.model_dump()
36
-
37
- if isinstance(obj, dict):
38
- return {str(k): _serialize_data(v) for k, v in obj.items()}
39
- if isinstance(obj, (list, tuple, set)):
40
- return [_serialize_data(item) for item in obj]
41
-
42
- if isinstance(obj, (str, int, float, bool, type(None))):
43
- return obj
44
-
45
- # Fallback
46
- return str(obj)
47
-
48
-
49
- def _prepare_serialized_args_kwargs(*args, **kwargs) -> tuple[list[Any], dict[str, Any]]:
50
- """Serialize args and kwargs before calling the wrapped function."""
51
- serialized_args = [_serialize_data(a) for a in args]
52
- serialized_kwargs = {k: _serialize_data(v) for k, v in kwargs.items()}
53
- return serialized_args, serialized_kwargs
54
-
55
-
56
- def push_intermediate_step(step_manager: IntermediateStepManager,
57
- identifier: str,
58
- function_name: str,
59
- event_type: IntermediateStepType,
60
- args: Any = None,
61
- kwargs: Any = None,
62
- output: Any = None,
63
- metadata: dict[str, Any] | None = None) -> None:
64
- """Push an intermediate step to the AIQ Toolkit Event Stream."""
65
-
66
- payload = IntermediateStepPayload(UUID=identifier,
67
- event_type=event_type,
68
- name=function_name,
69
- metadata=TraceMetadata(
70
- span_inputs=[args, kwargs],
71
- span_outputs=output,
72
- provided_metadata=metadata,
73
- ))
74
-
75
- step_manager.push_intermediate_step(payload)
76
-
77
-
78
- def track_function(func: Any = None, *, metadata: dict[str, Any] | None = None):
79
- """
80
- Decorator that can wrap any type of function (sync, async, generator,
81
- async generator) and executes "tracking logic" around it.
82
-
83
- - If the function is async, it will be wrapped in an async function.
84
- - If the function is a generator, it will be wrapped in a generator function.
85
- - If the function is an async generator, it will be wrapped in an async generator function.
86
- - If the function is sync, it will be wrapped in a sync function.
87
- """
88
- function_name: str = func.__name__ if func else "<unknown_function>"
89
-
90
- # If called as @track_function(...) but not immediately passed a function
91
- if func is None:
92
-
93
- def decorator_wrapper(actual_func):
94
- return track_function(actual_func, metadata=metadata)
95
-
96
- return decorator_wrapper
97
-
98
- # --- Validate metadata ---
99
- if metadata is not None:
100
- if not isinstance(metadata, dict):
101
- raise TypeError("metadata must be a dict[str, Any].")
102
- if any(not isinstance(k, str) for k in metadata.keys()):
103
- raise TypeError("All metadata keys must be strings.")
104
-
105
- # --- Now detect the function type and wrap accordingly ---
106
- if inspect.isasyncgenfunction(func):
107
- # ---------------------
108
- # ASYNC GENERATOR
109
- # ---------------------
110
-
111
- @functools.wraps(func)
112
- async def async_gen_wrapper(*args, **kwargs):
113
- step_manager: IntermediateStepManager = AIQContext.get().intermediate_step_manager
114
- # 1) Serialize input
115
- serialized_args, serialized_kwargs = _prepare_serialized_args_kwargs(*args, **kwargs)
116
-
117
- invocation_id = str(uuid.uuid4())
118
- push_intermediate_step(step_manager,
119
- invocation_id,
120
- function_name,
121
- IntermediateStepType.SPAN_START,
122
- args=serialized_args,
123
- kwargs=serialized_kwargs,
124
- metadata=metadata)
125
-
126
- # 2) Call the original async generator
127
- async for item in func(*args, **kwargs):
128
- # 3) Serialize the yielded item before yielding it
129
- serialized_item = _serialize_data(item)
130
- push_intermediate_step(step_manager,
131
- invocation_id,
132
- function_name,
133
- IntermediateStepType.SPAN_CHUNK,
134
- args=serialized_args,
135
- kwargs=serialized_kwargs,
136
- output=serialized_item,
137
- metadata=metadata)
138
- yield item # yield the original item
139
-
140
- push_intermediate_step(step_manager,
141
- invocation_id,
142
- function_name,
143
- IntermediateStepType.SPAN_END,
144
- args=serialized_args,
145
- kwargs=serialized_kwargs,
146
- output=None,
147
- metadata=metadata)
148
-
149
- # 4) Post-yield logic if any
150
-
151
- return async_gen_wrapper
152
-
153
- if inspect.iscoroutinefunction(func):
154
- # ---------------------
155
- # ASYNC FUNCTION
156
- # ---------------------
157
- @functools.wraps(func)
158
- async def async_wrapper(*args, **kwargs):
159
- step_manager: IntermediateStepManager = AIQContext.get().intermediate_step_manager
160
- serialized_args, serialized_kwargs = _prepare_serialized_args_kwargs(*args, **kwargs)
161
- invocation_id = str(uuid.uuid4())
162
- push_intermediate_step(step_manager,
163
- invocation_id,
164
- function_name,
165
- IntermediateStepType.SPAN_START,
166
- args=serialized_args,
167
- kwargs=serialized_kwargs,
168
- metadata=metadata)
169
-
170
- result = await func(*args, **kwargs)
171
-
172
- serialized_result = _serialize_data(result)
173
- push_intermediate_step(step_manager,
174
- invocation_id,
175
- function_name,
176
- IntermediateStepType.SPAN_END,
177
- args=serialized_args,
178
- kwargs=serialized_kwargs,
179
- output=serialized_result,
180
- metadata=metadata)
181
-
182
- return result
183
-
184
- return async_wrapper
185
-
186
- if inspect.isgeneratorfunction(func):
187
- # ---------------------
188
- # SYNC GENERATOR
189
- # ---------------------
190
- @functools.wraps(func)
191
- def sync_gen_wrapper(*args, **kwargs):
192
- step_manager: IntermediateStepManager = AIQContext.get().intermediate_step_manager
193
- serialized_args, serialized_kwargs = _prepare_serialized_args_kwargs(*args, **kwargs)
194
- invocation_id = str(uuid.uuid4())
195
- push_intermediate_step(step_manager,
196
- invocation_id,
197
- function_name,
198
- IntermediateStepType.SPAN_START,
199
- args=serialized_args,
200
- kwargs=serialized_kwargs,
201
- metadata=metadata)
202
-
203
- for item in func(*args, **kwargs):
204
- serialized_item = _serialize_data(item)
205
- push_intermediate_step(step_manager,
206
- invocation_id,
207
- function_name,
208
- IntermediateStepType.SPAN_CHUNK,
209
- args=serialized_args,
210
- kwargs=serialized_kwargs,
211
- output=serialized_item,
212
- metadata=metadata)
213
-
214
- yield item # yield the original item
215
-
216
- push_intermediate_step(step_manager,
217
- invocation_id,
218
- function_name,
219
- IntermediateStepType.SPAN_END,
220
- args=serialized_args,
221
- kwargs=serialized_kwargs,
222
- output=None,
223
- metadata=metadata)
224
-
225
- return sync_gen_wrapper
226
-
227
- @functools.wraps(func)
228
- def sync_wrapper(*args, **kwargs):
229
- step_manager: IntermediateStepManager = AIQContext.get().intermediate_step_manager
230
- serialized_args, serialized_kwargs = _prepare_serialized_args_kwargs(*args, **kwargs)
231
- invocation_id = str(uuid.uuid4())
232
- push_intermediate_step(step_manager,
233
- invocation_id,
234
- function_name,
235
- IntermediateStepType.SPAN_START,
236
- args=serialized_args,
237
- kwargs=serialized_kwargs,
238
- metadata=metadata)
239
-
240
- result = func(*args, **kwargs)
241
-
242
- serialized_result = _serialize_data(result)
243
- push_intermediate_step(step_manager,
244
- invocation_id,
245
- function_name,
246
- IntermediateStepType.SPAN_END,
247
- args=serialized_args,
248
- kwargs=serialized_kwargs,
249
- output=serialized_result,
250
- metadata=metadata)
251
-
252
- return result
253
-
254
- return sync_wrapper
File without changes
@@ -1,18 +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
- # If you have any global constants or defaults
17
- DEFAULT_MODEL_TYPE = "randomforest"
18
- DEFAULT_MATRIX_LENGTH = 10
@@ -1,75 +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
- # forecasting/model_trainer.py
17
-
18
- import logging
19
-
20
- from aiq.profiler.forecasting.config import DEFAULT_MODEL_TYPE
21
- from aiq.profiler.forecasting.models import ForecastingBaseModel
22
- from aiq.profiler.forecasting.models import LinearModel
23
- from aiq.profiler.forecasting.models import RandomForestModel
24
- from aiq.profiler.intermediate_property_adapter import IntermediatePropertyAdaptor
25
-
26
- logger = logging.getLogger(__name__)
27
-
28
-
29
- def create_model(model_type: str) -> ForecastingBaseModel:
30
- """
31
- A simple factory method that returns a model instance
32
- based on the input string. Extend this with more model
33
- classes (e.g., PolynomialModel, RandomForestModel, etc.).
34
- """
35
- if model_type == "linear":
36
- return LinearModel()
37
- if model_type == "randomforest":
38
- return RandomForestModel()
39
-
40
- raise ValueError(f"Unsupported model_type: {model_type}")
41
-
42
-
43
- class ModelTrainer:
44
- """
45
- Orchestrates data preprocessing, training, and returning
46
- a fitted model.
47
-
48
- Parameters
49
- ----------
50
- model_type: str, default = "randomforest"
51
- The type of model to train. Options include "linear" and "randomforest".
52
- """
53
-
54
- def __init__(self, model_type: str = DEFAULT_MODEL_TYPE):
55
- self.model_type = model_type
56
- self._model = create_model(self.model_type)
57
-
58
- def train(self, raw_stats: list[list[IntermediatePropertyAdaptor]]) -> ForecastingBaseModel:
59
- """
60
- Train the model using the `raw_stats` training data.
61
-
62
- Parameters
63
- ----------
64
- raw_stats: list[list[IntermediatePropertyAdaptor]]
65
- Stats collected by the profiler.
66
-
67
- Returns
68
- -------
69
- ForecastingBaseModel
70
- A fitted model.
71
- """
72
-
73
- self._model.fit(raw_stats)
74
-
75
- return self._model
@@ -1,22 +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
- # forecasting/models/__init__.py
17
-
18
- from .forecasting_base_model import ForecastingBaseModel
19
- from .linear_model import LinearModel
20
- from .random_forest_regressor import RandomForestModel
21
-
22
- __all__ = ["ForecastingBaseModel", "LinearModel", "RandomForestModel"]
@@ -1,40 +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
- # forecasting/models/base_model.py
17
-
18
- from abc import ABC, abstractmethod
19
- import numpy as np
20
-
21
-
22
- class ForecastingBaseModel(ABC):
23
- """
24
- Abstract base class for all models in this package.
25
- """
26
-
27
- @abstractmethod
28
- def fit(self, raw_stats):
29
- """
30
- Train/fine-tune the model on the provided dataset.
31
- """
32
- pass
33
-
34
- @abstractmethod
35
- def predict(self, raw_stats) -> np.ndarray:
36
- """
37
- Predict using the trained model.
38
- Returns a np.ndarray, shape = (N, 4).
39
- """
40
- pass
@@ -1,196 +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 logging
17
-
18
- import numpy as np
19
-
20
- from aiq.profiler.forecasting.models.forecasting_base_model import ForecastingBaseModel
21
- from aiq.profiler.intermediate_property_adapter import IntermediatePropertyAdaptor
22
-
23
- logger = logging.getLogger(__name__)
24
-
25
-
26
- class LinearModel(ForecastingBaseModel):
27
- """
28
- A linear regression model that conforms to the BaseModel interface.
29
- """
30
-
31
- def __init__(self):
32
- super().__init__()
33
-
34
- try:
35
- from sklearn.linear_model import LinearRegression
36
- except ImportError:
37
- logger.error("scikit-learn is not installed. Please install scikit-learn to use the LinearModel "
38
- "profiling model or install `aiq[profiler]` to install all necessary profiling packages.")
39
-
40
- raise
41
-
42
- self.model = LinearRegression()
43
- self.matrix_length = None
44
-
45
- def fit(self, raw_stats: list[list[IntermediatePropertyAdaptor]]):
46
- """
47
- X: shape (N, M) # M = matrix_length * 4
48
- y: shape (N, 4)
49
- """
50
- x_flat, y_flat = self._prep_for_model_training(raw_stats)
51
-
52
- logger.info("Training dataset size: X=%s, y=%s", x_flat.shape, y_flat.shape)
53
-
54
- # 3) Fit
55
- self.model.fit(x_flat, y_flat)
56
-
57
- def predict(self, raw_stats: list[list[IntermediatePropertyAdaptor]]) -> np.ndarray:
58
- """
59
- Predict using the fitted linear model.
60
- Returns shape (N, 4)
61
- """
62
- X = self._prep_single(raw_stats)
63
- return self.model.predict(X)
64
-
65
- def _prep_single(self, raw_stats: list[list[IntermediatePropertyAdaptor]]) -> np.ndarray:
66
- arr, _ = self._extract_token_usage_meta(raw_stats)
67
- arr = arr[0]
68
- n_rows = arr.shape[0]
69
-
70
- matrix_length = self.matrix_length
71
-
72
- assert matrix_length is not None, "matrix_length must be set before calling _prep_single"
73
-
74
- if n_rows >= matrix_length:
75
- # Keep the latest matrix_length rows
76
- x_mat = arr[-matrix_length:, :]
77
- else:
78
- # Pad with zeros at the top
79
- pad_size = matrix_length - n_rows
80
- pad_block = np.zeros((pad_size, arr.shape[1]), dtype=arr.dtype)
81
- x_mat = np.vstack([pad_block, arr])
82
-
83
- return x_mat
84
-
85
- def _prep_for_model_training(self, raw_stats: list[list[IntermediatePropertyAdaptor]]):
86
- raw_matrices, matrix_length = self._extract_token_usage_meta(raw_stats)
87
-
88
- self.matrix_length = matrix_length
89
-
90
- x_list = []
91
- y_list = []
92
- for arr in raw_matrices:
93
- samples = self._preprocess_for_forecasting(arr, matrix_length)
94
- for (x_mat, y_mat) in samples:
95
- x_list.append(x_mat)
96
- y_list.append(y_mat)
97
-
98
- # 2) Flatten features
99
- x_flat, y_flat = self._flatten_features(x_list, y_list)
100
-
101
- return x_flat, y_flat
102
-
103
- def _extract_token_usage_meta(self, all_requests_data: list[list[IntermediatePropertyAdaptor]]):
104
- import math
105
-
106
- all_run_data = []
107
- call_stack_sizes = []
108
-
109
- for prompt in all_requests_data:
110
- run_data = []
111
- seconds_between_call_map = {}
112
-
113
- for stat in prompt:
114
- if stat.event_type.value == "LLM_START":
115
- seconds_between_call_map[stat.UUID] = stat.seconds_between_calls
116
-
117
- if stat.event_type.value == "LLM_END":
118
- step_data = [
119
- seconds_between_call_map[stat.UUID],
120
- stat.token_usage.prompt_tokens,
121
- stat.token_usage.completion_tokens
122
- ]
123
-
124
- run_data.append(step_data)
125
-
126
- all_run_data.append(run_data)
127
- call_stack_sizes.append(len(run_data))
128
-
129
- all_run_data = [np.array(run) for run in all_run_data]
130
- recommended_matrix_length = math.ceil(sum(call_stack_sizes) / len(call_stack_sizes))
131
-
132
- return all_run_data, recommended_matrix_length
133
-
134
- def _preprocess_for_forecasting(self, arr: np.ndarray, matrix_length: int):
135
- """
136
- Given a 2D NumPy array `arr` of shape (n_rows, 4), generate a list of
137
- (input_array, output_array) pairs for forecasting, each of shape:
138
-
139
- - input_array: (matrix_length, 4) after padding/trimming
140
- - output_array: (1, 4)
141
- """
142
- n_rows = arr.shape[0]
143
-
144
- # partial_sums[i] = sum of arr[i:] per column
145
- partial_sums = np.flip(np.cumsum(np.flip(arr, axis=0), axis=0), axis=0)
146
-
147
- samples = []
148
- for i in range(n_rows):
149
- x_untrimmed = arr[:i + 1, :]
150
- # Trim or pad
151
- current_len = x_untrimmed.shape[0]
152
- if current_len > matrix_length:
153
- x_mat = x_untrimmed[-matrix_length:, :]
154
- elif current_len < matrix_length:
155
- pad_size = matrix_length - current_len
156
- pad_block = np.zeros((pad_size, x_untrimmed.shape[1]), dtype=arr.dtype)
157
- x_mat = np.vstack([pad_block, x_untrimmed])
158
- else:
159
- x_mat = x_untrimmed
160
-
161
- # Compute output
162
- if i == n_rows - 1:
163
- y_vec = np.array([0, 0, 0, 0], dtype=arr.dtype)
164
- else:
165
- n_below = n_rows - (i + 1)
166
- sum_below = partial_sums[i + 1]
167
- avg_col0 = sum_below[0] / n_below
168
- sum_rest = sum_below[1:]
169
- y_vec = np.concatenate(([avg_col0], sum_rest))
170
-
171
- samples.append((x_mat, y_vec.reshape(1, 4)))
172
-
173
- return samples
174
-
175
- def _flatten_features(self, x_list, y_list):
176
- """
177
- x_list: list of arrays, each of shape (matrix_length, 4)
178
- y_list: list of arrays, each of shape (1, 4)
179
-
180
- Returns:
181
- x_flat: np.array of shape (N, matrix_length*4)
182
- y_flat: np.array of shape (N, 4)
183
- """
184
- flattened_x = []
185
- flattened_y = []
186
-
187
- for x_mat, y_mat in zip(x_list, y_list):
188
- x_1d = x_mat.flatten() # shape -> (matrix_length*4,)
189
- y_1d = y_mat.flatten() # shape -> (4,)
190
- flattened_x.append(x_1d)
191
- flattened_y.append(y_1d)
192
-
193
- x_flat = np.array(flattened_x)
194
- y_flat = np.array(flattened_y)
195
- logger.debug("Flattened features to shapes: %s (X), %s (y).", x_flat.shape, y_flat.shape)
196
- return x_flat, y_flat