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.
- aiqtoolkit-1.1.0a20251020.dist-info/METADATA +37 -0
- aiqtoolkit-1.1.0a20251020.dist-info/RECORD +4 -0
- {aiqtoolkit-1.1.0a20250515.dist-info → aiqtoolkit-1.1.0a20251020.dist-info}/WHEEL +1 -1
- aiqtoolkit-1.1.0a20251020.dist-info/top_level.txt +1 -0
- aiq/agent/__init__.py +0 -0
- aiq/agent/base.py +0 -76
- aiq/agent/dual_node.py +0 -67
- aiq/agent/react_agent/__init__.py +0 -0
- aiq/agent/react_agent/agent.py +0 -322
- aiq/agent/react_agent/output_parser.py +0 -104
- aiq/agent/react_agent/prompt.py +0 -46
- aiq/agent/react_agent/register.py +0 -148
- aiq/agent/reasoning_agent/__init__.py +0 -0
- aiq/agent/reasoning_agent/reasoning_agent.py +0 -224
- aiq/agent/register.py +0 -23
- aiq/agent/rewoo_agent/__init__.py +0 -0
- aiq/agent/rewoo_agent/agent.py +0 -410
- aiq/agent/rewoo_agent/prompt.py +0 -108
- aiq/agent/rewoo_agent/register.py +0 -158
- aiq/agent/tool_calling_agent/__init__.py +0 -0
- aiq/agent/tool_calling_agent/agent.py +0 -123
- aiq/agent/tool_calling_agent/register.py +0 -105
- aiq/builder/__init__.py +0 -0
- aiq/builder/builder.py +0 -223
- aiq/builder/component_utils.py +0 -303
- aiq/builder/context.py +0 -227
- aiq/builder/embedder.py +0 -24
- aiq/builder/eval_builder.py +0 -120
- aiq/builder/evaluator.py +0 -29
- aiq/builder/framework_enum.py +0 -24
- aiq/builder/front_end.py +0 -73
- aiq/builder/function.py +0 -297
- aiq/builder/function_base.py +0 -376
- aiq/builder/function_info.py +0 -627
- aiq/builder/intermediate_step_manager.py +0 -135
- aiq/builder/llm.py +0 -25
- aiq/builder/retriever.py +0 -25
- aiq/builder/user_interaction_manager.py +0 -71
- aiq/builder/workflow.py +0 -143
- aiq/builder/workflow_builder.py +0 -757
- aiq/cli/__init__.py +0 -14
- aiq/cli/cli_utils/__init__.py +0 -0
- aiq/cli/cli_utils/config_override.py +0 -231
- aiq/cli/cli_utils/validation.py +0 -37
- aiq/cli/commands/__init__.py +0 -0
- aiq/cli/commands/configure/__init__.py +0 -0
- aiq/cli/commands/configure/channel/__init__.py +0 -0
- aiq/cli/commands/configure/channel/add.py +0 -28
- aiq/cli/commands/configure/channel/channel.py +0 -36
- aiq/cli/commands/configure/channel/remove.py +0 -30
- aiq/cli/commands/configure/channel/update.py +0 -30
- aiq/cli/commands/configure/configure.py +0 -33
- aiq/cli/commands/evaluate.py +0 -139
- aiq/cli/commands/info/__init__.py +0 -14
- aiq/cli/commands/info/info.py +0 -39
- aiq/cli/commands/info/list_channels.py +0 -32
- aiq/cli/commands/info/list_components.py +0 -129
- aiq/cli/commands/info/list_mcp.py +0 -126
- aiq/cli/commands/registry/__init__.py +0 -14
- aiq/cli/commands/registry/publish.py +0 -88
- aiq/cli/commands/registry/pull.py +0 -118
- aiq/cli/commands/registry/registry.py +0 -38
- aiq/cli/commands/registry/remove.py +0 -108
- aiq/cli/commands/registry/search.py +0 -155
- aiq/cli/commands/start.py +0 -250
- aiq/cli/commands/uninstall.py +0 -83
- aiq/cli/commands/validate.py +0 -47
- aiq/cli/commands/workflow/__init__.py +0 -14
- aiq/cli/commands/workflow/templates/__init__.py.j2 +0 -0
- aiq/cli/commands/workflow/templates/config.yml.j2 +0 -16
- aiq/cli/commands/workflow/templates/pyproject.toml.j2 +0 -22
- aiq/cli/commands/workflow/templates/register.py.j2 +0 -5
- aiq/cli/commands/workflow/templates/workflow.py.j2 +0 -36
- aiq/cli/commands/workflow/workflow.py +0 -37
- aiq/cli/commands/workflow/workflow_commands.py +0 -313
- aiq/cli/entrypoint.py +0 -133
- aiq/cli/main.py +0 -44
- aiq/cli/register_workflow.py +0 -408
- aiq/cli/type_registry.py +0 -879
- aiq/data_models/__init__.py +0 -14
- aiq/data_models/api_server.py +0 -588
- aiq/data_models/common.py +0 -143
- aiq/data_models/component.py +0 -46
- aiq/data_models/component_ref.py +0 -135
- aiq/data_models/config.py +0 -349
- aiq/data_models/dataset_handler.py +0 -122
- aiq/data_models/discovery_metadata.py +0 -286
- aiq/data_models/embedder.py +0 -26
- aiq/data_models/evaluate.py +0 -104
- aiq/data_models/evaluator.py +0 -26
- aiq/data_models/front_end.py +0 -26
- aiq/data_models/function.py +0 -30
- aiq/data_models/function_dependencies.py +0 -64
- aiq/data_models/interactive.py +0 -237
- aiq/data_models/intermediate_step.py +0 -269
- aiq/data_models/invocation_node.py +0 -38
- aiq/data_models/llm.py +0 -26
- aiq/data_models/logging.py +0 -26
- aiq/data_models/memory.py +0 -26
- aiq/data_models/profiler.py +0 -53
- aiq/data_models/registry_handler.py +0 -26
- aiq/data_models/retriever.py +0 -30
- aiq/data_models/step_adaptor.py +0 -64
- aiq/data_models/streaming.py +0 -33
- aiq/data_models/swe_bench_model.py +0 -54
- aiq/data_models/telemetry_exporter.py +0 -26
- aiq/embedder/__init__.py +0 -0
- aiq/embedder/langchain_client.py +0 -41
- aiq/embedder/nim_embedder.py +0 -58
- aiq/embedder/openai_embedder.py +0 -42
- aiq/embedder/register.py +0 -24
- aiq/eval/__init__.py +0 -14
- aiq/eval/config.py +0 -42
- aiq/eval/dataset_handler/__init__.py +0 -0
- aiq/eval/dataset_handler/dataset_downloader.py +0 -106
- aiq/eval/dataset_handler/dataset_filter.py +0 -52
- aiq/eval/dataset_handler/dataset_handler.py +0 -169
- aiq/eval/evaluate.py +0 -325
- aiq/eval/evaluator/__init__.py +0 -14
- aiq/eval/evaluator/evaluator_model.py +0 -44
- aiq/eval/intermediate_step_adapter.py +0 -93
- aiq/eval/rag_evaluator/__init__.py +0 -0
- aiq/eval/rag_evaluator/evaluate.py +0 -138
- aiq/eval/rag_evaluator/register.py +0 -138
- aiq/eval/register.py +0 -23
- aiq/eval/remote_workflow.py +0 -128
- aiq/eval/runtime_event_subscriber.py +0 -52
- aiq/eval/swe_bench_evaluator/__init__.py +0 -0
- aiq/eval/swe_bench_evaluator/evaluate.py +0 -215
- aiq/eval/swe_bench_evaluator/register.py +0 -36
- aiq/eval/trajectory_evaluator/__init__.py +0 -0
- aiq/eval/trajectory_evaluator/evaluate.py +0 -118
- aiq/eval/trajectory_evaluator/register.py +0 -40
- aiq/eval/tunable_rag_evaluator/__init__.py +0 -0
- aiq/eval/tunable_rag_evaluator/evaluate.py +0 -263
- aiq/eval/tunable_rag_evaluator/register.py +0 -50
- aiq/eval/utils/__init__.py +0 -0
- aiq/eval/utils/output_uploader.py +0 -131
- aiq/eval/utils/tqdm_position_registry.py +0 -40
- aiq/front_ends/__init__.py +0 -14
- aiq/front_ends/console/__init__.py +0 -14
- aiq/front_ends/console/console_front_end_config.py +0 -32
- aiq/front_ends/console/console_front_end_plugin.py +0 -107
- aiq/front_ends/console/register.py +0 -25
- aiq/front_ends/cron/__init__.py +0 -14
- aiq/front_ends/fastapi/__init__.py +0 -14
- aiq/front_ends/fastapi/fastapi_front_end_config.py +0 -150
- aiq/front_ends/fastapi/fastapi_front_end_plugin.py +0 -103
- aiq/front_ends/fastapi/fastapi_front_end_plugin_worker.py +0 -607
- aiq/front_ends/fastapi/intermediate_steps_subscriber.py +0 -80
- aiq/front_ends/fastapi/job_store.py +0 -161
- aiq/front_ends/fastapi/main.py +0 -70
- aiq/front_ends/fastapi/message_handler.py +0 -279
- aiq/front_ends/fastapi/message_validator.py +0 -345
- aiq/front_ends/fastapi/register.py +0 -25
- aiq/front_ends/fastapi/response_helpers.py +0 -195
- aiq/front_ends/fastapi/step_adaptor.py +0 -320
- aiq/front_ends/fastapi/websocket.py +0 -148
- aiq/front_ends/mcp/__init__.py +0 -14
- aiq/front_ends/mcp/mcp_front_end_config.py +0 -32
- aiq/front_ends/mcp/mcp_front_end_plugin.py +0 -93
- aiq/front_ends/mcp/register.py +0 -27
- aiq/front_ends/mcp/tool_converter.py +0 -242
- aiq/front_ends/register.py +0 -22
- aiq/front_ends/simple_base/__init__.py +0 -14
- aiq/front_ends/simple_base/simple_front_end_plugin_base.py +0 -52
- aiq/llm/__init__.py +0 -0
- aiq/llm/nim_llm.py +0 -45
- aiq/llm/openai_llm.py +0 -45
- aiq/llm/register.py +0 -22
- aiq/llm/utils/__init__.py +0 -14
- aiq/llm/utils/env_config_value.py +0 -94
- aiq/llm/utils/error.py +0 -17
- aiq/memory/__init__.py +0 -20
- aiq/memory/interfaces.py +0 -183
- aiq/memory/models.py +0 -112
- aiq/meta/module_to_distro.json +0 -3
- aiq/meta/pypi.md +0 -58
- aiq/observability/__init__.py +0 -0
- aiq/observability/async_otel_listener.py +0 -429
- aiq/observability/register.py +0 -99
- aiq/plugins/.namespace +0 -1
- aiq/profiler/__init__.py +0 -0
- aiq/profiler/callbacks/__init__.py +0 -0
- aiq/profiler/callbacks/agno_callback_handler.py +0 -295
- aiq/profiler/callbacks/base_callback_class.py +0 -20
- aiq/profiler/callbacks/langchain_callback_handler.py +0 -278
- aiq/profiler/callbacks/llama_index_callback_handler.py +0 -205
- aiq/profiler/callbacks/semantic_kernel_callback_handler.py +0 -238
- aiq/profiler/callbacks/token_usage_base_model.py +0 -27
- aiq/profiler/data_frame_row.py +0 -51
- aiq/profiler/decorators/__init__.py +0 -0
- aiq/profiler/decorators/framework_wrapper.py +0 -131
- aiq/profiler/decorators/function_tracking.py +0 -254
- aiq/profiler/forecasting/__init__.py +0 -0
- aiq/profiler/forecasting/config.py +0 -18
- aiq/profiler/forecasting/model_trainer.py +0 -75
- aiq/profiler/forecasting/models/__init__.py +0 -22
- aiq/profiler/forecasting/models/forecasting_base_model.py +0 -40
- aiq/profiler/forecasting/models/linear_model.py +0 -196
- aiq/profiler/forecasting/models/random_forest_regressor.py +0 -268
- aiq/profiler/inference_metrics_model.py +0 -25
- aiq/profiler/inference_optimization/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/__init__.py +0 -0
- aiq/profiler/inference_optimization/bottleneck_analysis/nested_stack_analysis.py +0 -452
- aiq/profiler/inference_optimization/bottleneck_analysis/simple_stack_analysis.py +0 -258
- aiq/profiler/inference_optimization/data_models.py +0 -386
- aiq/profiler/inference_optimization/experimental/__init__.py +0 -0
- aiq/profiler/inference_optimization/experimental/concurrency_spike_analysis.py +0 -468
- aiq/profiler/inference_optimization/experimental/prefix_span_analysis.py +0 -405
- aiq/profiler/inference_optimization/llm_metrics.py +0 -212
- aiq/profiler/inference_optimization/prompt_caching.py +0 -163
- aiq/profiler/inference_optimization/token_uniqueness.py +0 -107
- aiq/profiler/inference_optimization/workflow_runtimes.py +0 -72
- aiq/profiler/intermediate_property_adapter.py +0 -102
- aiq/profiler/profile_runner.py +0 -433
- aiq/profiler/utils.py +0 -184
- aiq/registry_handlers/__init__.py +0 -0
- aiq/registry_handlers/local/__init__.py +0 -0
- aiq/registry_handlers/local/local_handler.py +0 -176
- aiq/registry_handlers/local/register_local.py +0 -37
- aiq/registry_handlers/metadata_factory.py +0 -60
- aiq/registry_handlers/package_utils.py +0 -198
- aiq/registry_handlers/pypi/__init__.py +0 -0
- aiq/registry_handlers/pypi/pypi_handler.py +0 -251
- aiq/registry_handlers/pypi/register_pypi.py +0 -40
- aiq/registry_handlers/register.py +0 -21
- aiq/registry_handlers/registry_handler_base.py +0 -157
- aiq/registry_handlers/rest/__init__.py +0 -0
- aiq/registry_handlers/rest/register_rest.py +0 -56
- aiq/registry_handlers/rest/rest_handler.py +0 -237
- aiq/registry_handlers/schemas/__init__.py +0 -0
- aiq/registry_handlers/schemas/headers.py +0 -42
- aiq/registry_handlers/schemas/package.py +0 -68
- aiq/registry_handlers/schemas/publish.py +0 -63
- aiq/registry_handlers/schemas/pull.py +0 -82
- aiq/registry_handlers/schemas/remove.py +0 -36
- aiq/registry_handlers/schemas/search.py +0 -91
- aiq/registry_handlers/schemas/status.py +0 -47
- aiq/retriever/__init__.py +0 -0
- aiq/retriever/interface.py +0 -37
- aiq/retriever/milvus/__init__.py +0 -14
- aiq/retriever/milvus/register.py +0 -81
- aiq/retriever/milvus/retriever.py +0 -228
- aiq/retriever/models.py +0 -74
- aiq/retriever/nemo_retriever/__init__.py +0 -14
- aiq/retriever/nemo_retriever/register.py +0 -60
- aiq/retriever/nemo_retriever/retriever.py +0 -190
- aiq/retriever/register.py +0 -22
- aiq/runtime/__init__.py +0 -14
- aiq/runtime/loader.py +0 -188
- aiq/runtime/runner.py +0 -176
- aiq/runtime/session.py +0 -140
- aiq/runtime/user_metadata.py +0 -131
- aiq/settings/__init__.py +0 -0
- aiq/settings/global_settings.py +0 -318
- aiq/test/.namespace +0 -1
- aiq/tool/__init__.py +0 -0
- aiq/tool/code_execution/__init__.py +0 -0
- aiq/tool/code_execution/code_sandbox.py +0 -188
- aiq/tool/code_execution/local_sandbox/Dockerfile.sandbox +0 -60
- aiq/tool/code_execution/local_sandbox/__init__.py +0 -13
- aiq/tool/code_execution/local_sandbox/local_sandbox_server.py +0 -83
- aiq/tool/code_execution/local_sandbox/sandbox.requirements.txt +0 -4
- aiq/tool/code_execution/local_sandbox/start_local_sandbox.sh +0 -25
- aiq/tool/code_execution/register.py +0 -70
- aiq/tool/code_execution/utils.py +0 -100
- aiq/tool/datetime_tools.py +0 -42
- aiq/tool/document_search.py +0 -141
- aiq/tool/github_tools/__init__.py +0 -0
- aiq/tool/github_tools/create_github_commit.py +0 -133
- aiq/tool/github_tools/create_github_issue.py +0 -87
- aiq/tool/github_tools/create_github_pr.py +0 -106
- aiq/tool/github_tools/get_github_file.py +0 -106
- aiq/tool/github_tools/get_github_issue.py +0 -166
- aiq/tool/github_tools/get_github_pr.py +0 -256
- aiq/tool/github_tools/update_github_issue.py +0 -100
- aiq/tool/mcp/__init__.py +0 -14
- aiq/tool/mcp/mcp_client.py +0 -220
- aiq/tool/mcp/mcp_tool.py +0 -95
- aiq/tool/memory_tools/__init__.py +0 -0
- aiq/tool/memory_tools/add_memory_tool.py +0 -79
- aiq/tool/memory_tools/delete_memory_tool.py +0 -67
- aiq/tool/memory_tools/get_memory_tool.py +0 -72
- aiq/tool/nvidia_rag.py +0 -95
- aiq/tool/register.py +0 -37
- aiq/tool/retriever.py +0 -89
- aiq/tool/server_tools.py +0 -63
- aiq/utils/__init__.py +0 -0
- aiq/utils/data_models/__init__.py +0 -0
- aiq/utils/data_models/schema_validator.py +0 -58
- aiq/utils/debugging_utils.py +0 -43
- aiq/utils/exception_handlers/__init__.py +0 -0
- aiq/utils/exception_handlers/schemas.py +0 -114
- aiq/utils/io/__init__.py +0 -0
- aiq/utils/io/yaml_tools.py +0 -119
- aiq/utils/metadata_utils.py +0 -74
- aiq/utils/optional_imports.py +0 -142
- aiq/utils/producer_consumer_queue.py +0 -178
- aiq/utils/reactive/__init__.py +0 -0
- aiq/utils/reactive/base/__init__.py +0 -0
- aiq/utils/reactive/base/observable_base.py +0 -65
- aiq/utils/reactive/base/observer_base.py +0 -55
- aiq/utils/reactive/base/subject_base.py +0 -79
- aiq/utils/reactive/observable.py +0 -59
- aiq/utils/reactive/observer.py +0 -76
- aiq/utils/reactive/subject.py +0 -131
- aiq/utils/reactive/subscription.py +0 -49
- aiq/utils/settings/__init__.py +0 -0
- aiq/utils/settings/global_settings.py +0 -197
- aiq/utils/type_converter.py +0 -232
- aiq/utils/type_utils.py +0 -397
- aiq/utils/url_utils.py +0 -27
- aiqtoolkit-1.1.0a20250515.dist-info/METADATA +0 -331
- aiqtoolkit-1.1.0a20250515.dist-info/RECORD +0 -316
- aiqtoolkit-1.1.0a20250515.dist-info/entry_points.txt +0 -17
- aiqtoolkit-1.1.0a20250515.dist-info/licenses/LICENSE-3rd-party.txt +0 -3686
- aiqtoolkit-1.1.0a20250515.dist-info/licenses/LICENSE.md +0 -201
- aiqtoolkit-1.1.0a20250515.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,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.""")
|
aiq/tool/code_execution/utils.py
DELETED
|
@@ -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]
|
aiq/tool/datetime_tools.py
DELETED
|
@@ -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.")
|