aiqtoolkit 1.1.0a20250516__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.0a20250516.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 -176
  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.0a20250516.dist-info/METADATA +0 -331
  315. aiqtoolkit-1.1.0a20250516.dist-info/RECORD +0 -316
  316. aiqtoolkit-1.1.0a20250516.dist-info/entry_points.txt +0 -17
  317. aiqtoolkit-1.1.0a20250516.dist-info/licenses/LICENSE-3rd-party.txt +0 -3686
  318. aiqtoolkit-1.1.0a20250516.dist-info/licenses/LICENSE.md +0 -201
  319. aiqtoolkit-1.1.0a20250516.dist-info/top_level.txt +0 -1
@@ -1,188 +0,0 @@
1
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import abc
16
- import json
17
- import logging
18
- from urllib.parse import urljoin
19
-
20
- import requests
21
- from pydantic import HttpUrl
22
-
23
- logger = logging.getLogger(__file__)
24
-
25
-
26
- class Sandbox(abc.ABC):
27
- """Code execution sandbox.
28
-
29
- Args:
30
- host: Optional[str] = '127.0.0.1' - Host of the sandbox server.
31
- Can also be specified through NEMO_SKILLS_SANDBOX_HOST env var.
32
- port: Optional[str] = '5000' - Port of the sandbox server.
33
- Can also be specified through NEMO_SKILLS_SANDBOX_PORT env var.
34
- ssh_server: Optional[str] = None - SSH server for tunneling requests.
35
- Useful if server is running on slurm cluster to which there is an ssh access.
36
- Can also be specified through NEMO_SKILLS_SSH_SERVER env var.
37
- ssh_key_path: Optional[str] = None - Path to the ssh key for tunneling.
38
- Can also be specified through NEMO_SKILLS_SSH_KEY_PATH env var.
39
- """
40
-
41
- def __init__(
42
- self,
43
- *,
44
- uri: HttpUrl,
45
- ):
46
- self.url = self._get_execute_url(uri)
47
- session = requests.Session()
48
- adapter = requests.adapters.HTTPAdapter(pool_maxsize=1500, pool_connections=1500, max_retries=3)
49
- session.mount('http://', adapter)
50
- session.mount('https://', adapter)
51
- self.http_session = session
52
-
53
- def _send_request(self, request, timeout):
54
- output = self.http_session.post(
55
- url=self.url,
56
- data=json.dumps(request),
57
- timeout=timeout,
58
- headers={"Content-Type": "application/json"},
59
- )
60
- # retrying 502 errors
61
- if output.status_code == 502:
62
- raise requests.exceptions.Timeout
63
-
64
- return self._parse_request_output(output)
65
-
66
- @abc.abstractmethod
67
- def _parse_request_output(self, output):
68
- pass
69
-
70
- @abc.abstractmethod
71
- def _get_execute_url(self, uri):
72
- pass
73
-
74
- @abc.abstractmethod
75
- def _prepare_request(self, generated_code, timeout):
76
- pass
77
-
78
- async def execute_code(
79
- self,
80
- generated_code: str,
81
- timeout: float = 10.0,
82
- language: str = "python",
83
- max_output_characters: int = 1000,
84
- ) -> tuple[dict, str]:
85
-
86
- generated_code = generated_code.lstrip().rstrip().lstrip("`").rstrip("`")
87
- code_to_execute = """
88
- import traceback
89
- import json
90
- import os
91
- import warnings
92
- import contextlib
93
- import io
94
- warnings.filterwarnings('ignore')
95
- os.environ['OPENBLAS_NUM_THREADS'] = '16'
96
- """
97
-
98
- code_to_execute += f"""
99
- \ngenerated_code = {repr(generated_code)}\n
100
- stdout = io.StringIO()
101
- stderr = io.StringIO()
102
-
103
- with contextlib.redirect_stdout(stdout), contextlib.redirect_stderr(stderr):
104
- try:
105
- exec(generated_code)
106
- status = "completed"
107
- except Exception:
108
- status = "error"
109
- stderr.write(traceback.format_exc())
110
- stdout = stdout.getvalue()
111
- stderr = stderr.getvalue()
112
- if len(stdout) > {max_output_characters}:
113
- stdout = stdout[:{max_output_characters}] + "<output cut>"
114
- if len(stderr) > {max_output_characters}:
115
- stderr = stderr[:{max_output_characters}] + "<output cut>"
116
- if stdout:
117
- stdout += "\\n"
118
- if stderr:
119
- stderr += "\\n"
120
- output = {{"process_status": status, "stdout": stdout, "stderr": stderr}}
121
- print(json.dumps(output))
122
- """
123
- request = self._prepare_request(code_to_execute, timeout)
124
- try:
125
- output = self._send_request(request, timeout)
126
- except requests.exceptions.Timeout:
127
- output = {"process_status": "timeout", "stdout": "", "stderr": "Timed out\n"}
128
- return output
129
-
130
-
131
- class LocalSandbox(Sandbox):
132
- """Locally hosted sandbox."""
133
-
134
- def _get_execute_url(self, uri):
135
- return urljoin(str(uri), "execute")
136
-
137
- def _parse_request_output(self, output):
138
- try:
139
- return output.json()
140
- except json.JSONDecodeError as e:
141
- logger.exception("Error parsing output: %s. %s", output.text, e)
142
- return {'process_status': 'error', 'stdout': '', 'stderr': 'Unknown error'}
143
-
144
- def _prepare_request(self, generated_code, timeout, language='python', **kwargs):
145
- return {
146
- "generated_code": generated_code,
147
- "timeout": timeout,
148
- "language": language,
149
- }
150
-
151
-
152
- class PistonSandbox(Sandbox):
153
- """Piston sandbox (https://github.com/engineer-man/piston)"""
154
-
155
- def _get_execute_url(self, uri):
156
- return urljoin(str(uri), "execute")
157
-
158
- def _parse_request_output(self, output):
159
- output = output.json()
160
- if output['run']['signal'] == "SIGKILL":
161
- return {'result': None, 'error_message': 'Unknown error: SIGKILL'}
162
- return json.loads(output['run']['output'])
163
-
164
- def _prepare_request(self, generated_code: str, timeout, **kwargs):
165
- return {
166
- "language": "py",
167
- "version": "3.10.0",
168
- "files": [{
169
- "content": generated_code,
170
- }],
171
- "stdin": "",
172
- "args": [],
173
- "run_timeout": timeout * 1000.0, # milliseconds
174
- "compile_memory_limit": -1,
175
- "run_memory_limit": -1,
176
- }
177
-
178
-
179
- sandboxes = {
180
- 'local': LocalSandbox,
181
- 'piston': PistonSandbox,
182
- }
183
-
184
-
185
- def get_sandbox(sandbox_type: str = "local", **kwargs):
186
- """A helper function to make it easier to set sandbox through cmd."""
187
- sandbox_class = sandboxes[sandbox_type.lower()]
188
- return sandbox_class(**kwargs)
@@ -1,60 +0,0 @@
1
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- # Use the base image with Python 3.10 and Flask
16
- FROM tiangolo/uwsgi-nginx-flask:python3.10
17
-
18
- # Install dependencies required for Lean 4 and other tools
19
- RUN apt-get update && \
20
- apt-get install -y curl git && \
21
- curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh -s -- -y && \
22
- /root/.elan/bin/elan toolchain install leanprover/lean4:v4.12.0 && \
23
- /root/.elan/bin/elan default leanprover/lean4:v4.12.0 && \
24
- /root/.elan/bin/elan self update
25
-
26
- # Set environment variables to include Lean and elan/lake in the PATH
27
- ENV PATH="/root/.elan/bin:$PATH"
28
-
29
- # Create Lean project directory and initialize a new Lean project with Mathlib4
30
- RUN mkdir -p /lean4 && cd /lean4 && \
31
- /root/.elan/bin/lake new my_project && \
32
- cd my_project && \
33
- echo 'leanprover/lean4:v4.12.0' > lean-toolchain && \
34
- echo 'require mathlib from git "https://github.com/leanprover-community/mathlib4" @ "v4.12.0"' >> lakefile.lean
35
-
36
- # Download and cache Mathlib4 to avoid recompiling, then build the project
37
- RUN cd /lean4/my_project && \
38
- /root/.elan/bin/lake exe cache get && \
39
- /root/.elan/bin/lake build
40
-
41
- # Set environment variables to include Lean project path
42
- ENV LEAN_PATH="/lean4/my_project"
43
- ENV PATH="/lean4/my_project:$PATH"
44
-
45
- # Set up application code and install Python dependencies
46
- COPY sandbox.requirements.txt /app/requirements.txt
47
- RUN pip install --no-cache-dir -r /app/requirements.txt
48
- COPY local_sandbox_server.py /app/main.py
49
-
50
- # Set the working directory to /app
51
- WORKDIR /app
52
-
53
- # Set Flask app environment variables and ports
54
- ARG UWSGI_CHEAPER
55
- ENV UWSGI_CHEAPER=$UWSGI_CHEAPER
56
-
57
- ARG UWSGI_PROCESSES
58
- ENV UWSGI_PROCESSES=$UWSGI_PROCESSES
59
-
60
- ENV LISTEN_PORT=6000
@@ -1,13 +0,0 @@
1
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
@@ -1,83 +0,0 @@
1
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import logging
16
- import multiprocessing
17
- import resource
18
- import sys
19
- from io import StringIO
20
-
21
- from flask import Flask
22
- from flask import request
23
-
24
- app = Flask(__name__)
25
-
26
-
27
- @app.after_request
28
- def add_hsts_header(response):
29
- response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
30
- response.headers['X-Content-Type-Options'] = 'nosniff'
31
- response.headers['X-Frame-Options'] = 'SAMEORIGIN'
32
- response.headers['X-XSS-Protection'] = '1; mode=block'
33
-
34
- return response
35
-
36
-
37
- def execute_python(generated_code, timeout):
38
- # running in a separate process to ensure any kind of crashes are properly handled
39
- queue = multiprocessing.Queue()
40
- process = multiprocessing.Process(target=execute_code_subprocess, args=(generated_code, queue))
41
- process.start()
42
- process.join(timeout=timeout)
43
-
44
- if process.is_alive(): # didn't finish successfully
45
- process.kill()
46
- return {"process_status": "timeout", "stdout": "", "stderr": "Timed out\n"}
47
-
48
- return queue.get()
49
-
50
-
51
- # need to memory-limit to avoid common errors of allocating too much
52
- # but this has to be done in a subprocess to not crush server itself
53
- def execute_code_subprocess(generated_code, queue):
54
- limit = 1024 * 1024 * 1024 * 10 # 10gb - somehow with a smaller limit the server dies when numpy is used
55
- resource.setrlimit(resource.RLIMIT_AS, (limit, limit))
56
- resource.setrlimit(resource.RLIMIT_DATA, (limit, limit))
57
-
58
- # this can be overriden inside generated code, so it's not a guaranteed protection
59
- sys.stdout = StringIO()
60
- try:
61
- exec(generated_code, {}) # pylint: disable=W0122
62
- queue.put(sys.stdout.getvalue())
63
- except Exception as e:
64
- print(f"Error: {str(e)}")
65
- queue.put({"process_status": "error", "stdout": "", "stderr": str(e) + "\n"})
66
-
67
-
68
- # Main Flask endpoint to handle execution requests
69
- @app.route("/execute", methods=["POST"])
70
- def execute():
71
- generated_code = request.json['generated_code']
72
- timeout = request.json['timeout']
73
- language = request.json.get('language', 'python')
74
-
75
- if language == 'python':
76
- return execute_python(generated_code, timeout)
77
- return {"process_status": "error", "stdout": "", "stderr": "Only python execution is supported"}
78
-
79
-
80
- if __name__ == '__main__':
81
- log = logging.getLogger('werkzeug')
82
- log.setLevel(logging.WARNING)
83
- app.run(port=6000)
@@ -1,4 +0,0 @@
1
- numpy
2
- pandas
3
- scipy
4
- ipython
@@ -1,25 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
-
17
- # NOTE: needs to run from the root of the repo!
18
-
19
- SANDBOX_NAME=${1:-'local-sandbox'}
20
- NUM_THREADS=10
21
-
22
-
23
- docker build --tag=${SANDBOX_NAME} --build-arg="UWSGI_PROCESSES=$((${NUM_THREADS} * 10))" --build-arg="UWSGI_CHEAPER=${NUM_THREADS}" -f Dockerfile.sandbox .
24
-
25
- docker run --network=host --rm --name=local-sandbox ${SANDBOX_NAME}
@@ -1,70 +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
- from typing import Literal
18
-
19
- from pydantic import BaseModel
20
- from pydantic import Field
21
- from pydantic import HttpUrl
22
-
23
- from aiq.builder.builder import Builder
24
- from aiq.builder.function_info import FunctionInfo
25
- from aiq.cli.register_workflow import register_function
26
- from aiq.data_models.function import FunctionBaseConfig
27
-
28
- logger = logging.getLogger(__name__)
29
-
30
-
31
- class CodeExecutionToolConfig(FunctionBaseConfig, name="code_execution"):
32
- """
33
- Tool for executing python code in a remotely hosted sandbox environment.
34
- """
35
- uri: HttpUrl = Field(default=HttpUrl("http://127.0.0.1:6000"),
36
- description="URI for the code execution sandbox server")
37
- sandbox_type: Literal["local", "piston"] = Field(default="local", description="The type of code execution sandbox")
38
- timeout: float = Field(default=10.0, description="Number of seconds to wait for a code execution request")
39
- max_output_characters: int = Field(default=1000, description="Maximum number of characters that can be returned")
40
-
41
-
42
- @register_function(config_type=CodeExecutionToolConfig)
43
- async def code_execution_tool(config: CodeExecutionToolConfig, builder: Builder):
44
- from aiq.tool.code_execution.code_sandbox import get_sandbox
45
-
46
- class CodeExecutionInputSchema(BaseModel):
47
- generated_code: str = Field(description="String containing the code to be executed")
48
-
49
- sandbox = get_sandbox(sandbox_type=config.sandbox_type, uri=config.uri)
50
-
51
- async def _execute_code(generated_code: str) -> dict:
52
- logger.info("Executing code in the sandbox at %s", config.uri)
53
- try:
54
- output = await sandbox.execute_code(
55
- generated_code=generated_code,
56
- language="python",
57
- timeout=config.timeout,
58
- max_output_characters=config.max_output_characters,
59
- )
60
- except Exception as e:
61
- logger.exception("Error when executing code in the sandbox, %s", e)
62
- return {"process_status": "error", "stdout": "", "stderr": e}
63
- return output
64
-
65
- yield FunctionInfo.from_fn(
66
- fn=_execute_code,
67
- input_schema=CodeExecutionInputSchema,
68
- description="""Executes the provied 'generated_code' in a python sandbox environment and returns
69
- a dictionary containing stdout, stderr, and the execution status, as well as a session_id. The
70
- session_id can be used to append to code that was previously executed.""")
@@ -1,100 +0,0 @@
1
- # Copyright (c) 2024-2025, NVIDIA CORPORATION. All rights reserved.
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import glob
16
- import logging
17
- import re
18
-
19
- LOG = logging.getLogger(__name__)
20
-
21
-
22
- def format_code_output(execution_dict: dict[str, str],
23
- code_output_begin: str,
24
- code_output_end: str,
25
- code_output_format: str = 'llama'):
26
- """Formatting code output to be displayed as an llm expects it."""
27
- if code_output_format == 'llama':
28
- output = execution_dict["process_status"]
29
- if execution_dict['stdout']:
30
- output += f"\n[stdout]\n{execution_dict['stdout']}[/stdout]"
31
- if execution_dict['stderr']:
32
- output += f"\n[stderr]\n{execution_dict['stderr']}[/stderr]"
33
- output = f"{code_output_begin}\n\n{output}{code_output_end}\n\n"
34
- elif code_output_format == 'qwen':
35
- output = ""
36
- if execution_dict['stdout']:
37
- output += f"{execution_dict['stdout']}"
38
- if execution_dict['stderr']:
39
- output += f"{execution_dict['stderr']}"
40
- if execution_dict['stderr'] and execution_dict['stdout']:
41
- LOG.warning("Both stdout and stderr are not empty. This shouldn't normally happen! %s", execution_dict)
42
- output = f"{code_output_begin}{output}{code_output_end}"
43
- else:
44
- raise ValueError(f"Unknown code_output_format: {code_output_format}")
45
-
46
- # wrapping with code output separators
47
- return output
48
-
49
-
50
- def _extract_between_separators(generation: str, separators: tuple[str, str], extract_all: bool = False):
51
- """Extracting all text between last occurrence of separators[0] and [1].
52
-
53
- If extract_all is True, returning a list with all occurrences of text between separators.
54
- """
55
- if extract_all:
56
- separators = [re.escape(sp) for sp in separators]
57
- pattern = f'{separators[0]}(.*?){separators[1]}'
58
- return re.findall(pattern, generation, re.DOTALL)
59
- return generation.split(separators[0])[-1].split(separators[1])[0]
60
-
61
-
62
- def extract_code_to_execute(generation: str, code_begin: str, code_end: str, extract_all: bool = False):
63
- return _extract_between_separators(generation, [code_begin, code_end], extract_all)
64
-
65
-
66
- def extract_code_output(generation: str, code_output_begin: str, code_output_end: str, extract_all: bool = False):
67
- return _extract_between_separators(generation, [code_output_begin, code_output_end], extract_all)
68
-
69
-
70
- def unroll_files(input_files):
71
- if len(input_files) == 0:
72
- raise ValueError("No files found with the given pattern.")
73
- total_files = 0
74
- for file_pattern in input_files:
75
- for file in sorted(glob.glob(file_pattern, recursive=True)):
76
- total_files += 1
77
- yield file
78
- if total_files == 0:
79
- raise ValueError("No files found with the given pattern.")
80
-
81
-
82
- def python_doc_to_cmd_help(doc_class, docs_prefix="", arg_prefix=""):
83
- """Converts python doc to cmd help format.
84
-
85
- Will color the args and change the format to match what we use in cmd help.
86
- """
87
- all_args = docs_prefix
88
- all_args += doc_class.__doc__.split("Args:")[1].rstrip()
89
- # \033[92m ... \033[0m - green in terminal
90
- colored_args = ""
91
- for line in all_args.split("\n"):
92
- if " " in line and " - " in line:
93
- # add colors
94
- line = line.replace(" ", " \033[92m").replace(" - ", "\033[0m - ")
95
- # fixing arg format
96
- line = line.replace(' \033[92m', f' \033[92m{arg_prefix}')
97
- # fixing indent
98
- line = line.replace(" ", " ").replace(" ", " ")
99
- colored_args += line + '\n'
100
- return colored_args[:-1]
@@ -1,42 +0,0 @@
1
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2
- # SPDX-License-Identifier: Apache-2.0
3
- #
4
- # Licensed under the Apache License, Version 2.0 (the "License");
5
- # you may not use this file except in compliance with the License.
6
- # You may obtain a copy of the License at
7
- #
8
- # http://www.apache.org/licenses/LICENSE-2.0
9
- #
10
- # Unless required by applicable law or agreed to in writing, software
11
- # distributed under the License is distributed on an "AS IS" BASIS,
12
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- # See the License for the specific language governing permissions and
14
- # limitations under the License.
15
-
16
- from aiq.builder.builder import Builder
17
- from aiq.builder.function_info import FunctionInfo
18
- from aiq.cli.register_workflow import register_function
19
- from aiq.data_models.function import FunctionBaseConfig
20
-
21
-
22
- class CurrentTimeToolConfig(FunctionBaseConfig, name="current_datetime"):
23
- """
24
- Simple tool which returns the current date and time in human readable format.
25
- """
26
- pass
27
-
28
-
29
- @register_function(config_type=CurrentTimeToolConfig)
30
- async def current_datetime(config: CurrentTimeToolConfig, builder: Builder):
31
-
32
- import datetime
33
-
34
- async def _get_current_time(unused: str) -> str:
35
-
36
- now = datetime.datetime.now() # Get current time
37
- now_human_readable = now.strftime(("%Y-%m-%d %H:%M:%S"))
38
-
39
- return f"The current time of day is {now_human_readable}" # Format time in H:MM AM/PM format
40
-
41
- yield FunctionInfo.from_fn(_get_current_time,
42
- description="Returns the current date and time in human readable format.")