alita-sdk 0.3.257__py3-none-any.whl → 0.3.584__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 alita-sdk might be problematic. Click here for more details.
- alita_sdk/cli/__init__.py +10 -0
- alita_sdk/cli/__main__.py +17 -0
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +155 -0
- alita_sdk/cli/agent_loader.py +215 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3794 -0
- alita_sdk/cli/callbacks.py +647 -0
- alita_sdk/cli/cli.py +168 -0
- alita_sdk/cli/config.py +306 -0
- alita_sdk/cli/context/__init__.py +30 -0
- alita_sdk/cli/context/cleanup.py +198 -0
- alita_sdk/cli/context/manager.py +731 -0
- alita_sdk/cli/context/message.py +285 -0
- alita_sdk/cli/context/strategies.py +289 -0
- alita_sdk/cli/context/token_estimation.py +127 -0
- alita_sdk/cli/formatting.py +182 -0
- alita_sdk/cli/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1073 -0
- alita_sdk/cli/mcp_loader.py +315 -0
- alita_sdk/cli/toolkit.py +327 -0
- alita_sdk/cli/toolkit_loader.py +85 -0
- alita_sdk/cli/tools/__init__.py +43 -0
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +1751 -0
- alita_sdk/cli/tools/planning.py +389 -0
- alita_sdk/cli/tools/terminal.py +414 -0
- alita_sdk/community/__init__.py +72 -12
- alita_sdk/community/inventory/__init__.py +236 -0
- alita_sdk/community/inventory/config.py +257 -0
- alita_sdk/community/inventory/enrichment.py +2137 -0
- alita_sdk/community/inventory/extractors.py +1469 -0
- alita_sdk/community/inventory/ingestion.py +3172 -0
- alita_sdk/community/inventory/knowledge_graph.py +1457 -0
- alita_sdk/community/inventory/parsers/__init__.py +218 -0
- alita_sdk/community/inventory/parsers/base.py +295 -0
- alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
- alita_sdk/community/inventory/parsers/go_parser.py +851 -0
- alita_sdk/community/inventory/parsers/html_parser.py +389 -0
- alita_sdk/community/inventory/parsers/java_parser.py +593 -0
- alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
- alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
- alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
- alita_sdk/community/inventory/parsers/python_parser.py +604 -0
- alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
- alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
- alita_sdk/community/inventory/parsers/text_parser.py +322 -0
- alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
- alita_sdk/community/inventory/patterns/__init__.py +61 -0
- alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
- alita_sdk/community/inventory/patterns/loader.py +348 -0
- alita_sdk/community/inventory/patterns/registry.py +198 -0
- alita_sdk/community/inventory/presets.py +535 -0
- alita_sdk/community/inventory/retrieval.py +1403 -0
- alita_sdk/community/inventory/toolkit.py +173 -0
- alita_sdk/community/inventory/toolkit_utils.py +176 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/__init__.py +11 -0
- alita_sdk/configurations/ado.py +148 -2
- alita_sdk/configurations/azure_search.py +1 -1
- alita_sdk/configurations/bigquery.py +1 -1
- alita_sdk/configurations/bitbucket.py +94 -2
- alita_sdk/configurations/browser.py +18 -0
- alita_sdk/configurations/carrier.py +19 -0
- alita_sdk/configurations/confluence.py +130 -1
- alita_sdk/configurations/delta_lake.py +1 -1
- alita_sdk/configurations/figma.py +76 -5
- alita_sdk/configurations/github.py +65 -1
- alita_sdk/configurations/gitlab.py +81 -0
- alita_sdk/configurations/google_places.py +17 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/openapi.py +323 -0
- alita_sdk/configurations/postman.py +1 -1
- alita_sdk/configurations/qtest.py +72 -3
- alita_sdk/configurations/report_portal.py +115 -0
- alita_sdk/configurations/salesforce.py +19 -0
- alita_sdk/configurations/service_now.py +1 -12
- alita_sdk/configurations/sharepoint.py +167 -0
- alita_sdk/configurations/sonar.py +18 -0
- alita_sdk/configurations/sql.py +20 -0
- alita_sdk/configurations/testio.py +101 -0
- alita_sdk/configurations/testrail.py +88 -0
- alita_sdk/configurations/xray.py +94 -1
- alita_sdk/configurations/zephyr_enterprise.py +94 -1
- alita_sdk/configurations/zephyr_essential.py +95 -0
- alita_sdk/runtime/clients/artifact.py +21 -4
- alita_sdk/runtime/clients/client.py +458 -67
- alita_sdk/runtime/clients/mcp_discovery.py +342 -0
- alita_sdk/runtime/clients/mcp_manager.py +262 -0
- alita_sdk/runtime/clients/sandbox_client.py +352 -0
- alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
- alita_sdk/runtime/langchain/assistant.py +183 -43
- alita_sdk/runtime/langchain/constants.py +647 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +209 -31
- alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaMarkdownLoader.py +66 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaPDFLoader.py +79 -10
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +52 -15
- alita_sdk/runtime/langchain/document_loaders/AlitaPythonLoader.py +9 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -4
- alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +15 -2
- alita_sdk/runtime/langchain/document_loaders/ImageParser.py +30 -0
- alita_sdk/runtime/langchain/document_loaders/constants.py +189 -41
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +4 -2
- alita_sdk/runtime/langchain/langraph_agent.py +493 -105
- alita_sdk/runtime/langchain/utils.py +118 -8
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- alita_sdk/runtime/skills/__init__.py +91 -0
- alita_sdk/runtime/skills/callbacks.py +498 -0
- alita_sdk/runtime/skills/discovery.py +540 -0
- alita_sdk/runtime/skills/executor.py +610 -0
- alita_sdk/runtime/skills/input_builder.py +371 -0
- alita_sdk/runtime/skills/models.py +330 -0
- alita_sdk/runtime/skills/registry.py +355 -0
- alita_sdk/runtime/skills/skill_runner.py +330 -0
- alita_sdk/runtime/toolkits/__init__.py +28 -0
- alita_sdk/runtime/toolkits/application.py +14 -4
- alita_sdk/runtime/toolkits/artifact.py +25 -9
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +782 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/skill_router.py +238 -0
- alita_sdk/runtime/toolkits/subgraph.py +11 -6
- alita_sdk/runtime/toolkits/tools.py +314 -70
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/__init__.py +24 -0
- alita_sdk/runtime/tools/application.py +16 -4
- alita_sdk/runtime/tools/artifact.py +367 -33
- alita_sdk/runtime/tools/data_analysis.py +183 -0
- alita_sdk/runtime/tools/function.py +100 -4
- alita_sdk/runtime/tools/graph.py +81 -0
- alita_sdk/runtime/tools/image_generation.py +218 -0
- alita_sdk/runtime/tools/llm.py +1032 -177
- alita_sdk/runtime/tools/loop.py +3 -1
- alita_sdk/runtime/tools/loop_output.py +3 -1
- alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
- alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
- alita_sdk/runtime/tools/mcp_server_tool.py +3 -1
- alita_sdk/runtime/tools/planning/__init__.py +36 -0
- alita_sdk/runtime/tools/planning/models.py +246 -0
- alita_sdk/runtime/tools/planning/wrapper.py +607 -0
- alita_sdk/runtime/tools/router.py +2 -1
- alita_sdk/runtime/tools/sandbox.py +375 -0
- alita_sdk/runtime/tools/skill_router.py +776 -0
- alita_sdk/runtime/tools/tool.py +3 -1
- alita_sdk/runtime/tools/vectorstore.py +69 -65
- alita_sdk/runtime/tools/vectorstore_base.py +163 -90
- alita_sdk/runtime/utils/AlitaCallback.py +137 -21
- alita_sdk/runtime/utils/constants.py +5 -1
- alita_sdk/runtime/utils/mcp_client.py +492 -0
- alita_sdk/runtime/utils/mcp_oauth.py +361 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +41 -14
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +48 -0
- alita_sdk/tools/__init__.py +135 -37
- alita_sdk/tools/ado/__init__.py +2 -2
- alita_sdk/tools/ado/repos/__init__.py +16 -19
- alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
- alita_sdk/tools/ado/test_plan/__init__.py +27 -8
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
- alita_sdk/tools/ado/wiki/__init__.py +28 -12
- alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
- alita_sdk/tools/ado/work_item/__init__.py +28 -12
- alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
- alita_sdk/tools/advanced_jira_mining/__init__.py +13 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +15 -11
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +14 -8
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +454 -110
- alita_sdk/tools/bitbucket/__init__.py +28 -19
- alita_sdk/tools/bitbucket/api_wrapper.py +285 -27
- alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
- alita_sdk/tools/browser/__init__.py +41 -16
- alita_sdk/tools/browser/crawler.py +3 -1
- alita_sdk/tools/browser/utils.py +15 -6
- alita_sdk/tools/carrier/__init__.py +18 -17
- alita_sdk/tools/carrier/backend_reports_tool.py +8 -4
- alita_sdk/tools/carrier/excel_reporter.py +8 -4
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/code/codeparser.py +1 -1
- alita_sdk/tools/chunkers/sematic/json_chunker.py +2 -1
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +12 -7
- alita_sdk/tools/cloud/azure/__init__.py +12 -7
- alita_sdk/tools/cloud/gcp/__init__.py +12 -7
- alita_sdk/tools/cloud/k8s/__init__.py +12 -7
- alita_sdk/tools/code/linter/__init__.py +10 -8
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +21 -13
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +22 -14
- alita_sdk/tools/confluence/api_wrapper.py +197 -58
- alita_sdk/tools/confluence/loader.py +14 -2
- alita_sdk/tools/custom_open_api/__init__.py +12 -5
- alita_sdk/tools/elastic/__init__.py +11 -8
- alita_sdk/tools/elitea_base.py +546 -64
- alita_sdk/tools/figma/__init__.py +60 -11
- alita_sdk/tools/figma/api_wrapper.py +1400 -167
- alita_sdk/tools/figma/figma_client.py +73 -0
- alita_sdk/tools/figma/toon_tools.py +2748 -0
- alita_sdk/tools/github/__init__.py +18 -17
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +81 -12
- alita_sdk/tools/github/schemas.py +2 -1
- alita_sdk/tools/github/tool.py +5 -1
- alita_sdk/tools/gitlab/__init__.py +19 -13
- alita_sdk/tools/gitlab/api_wrapper.py +256 -80
- alita_sdk/tools/gitlab_org/__init__.py +14 -10
- alita_sdk/tools/google/bigquery/__init__.py +14 -13
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +21 -11
- alita_sdk/tools/jira/__init__.py +22 -11
- alita_sdk/tools/jira/api_wrapper.py +315 -168
- alita_sdk/tools/keycloak/__init__.py +11 -8
- alita_sdk/tools/localgit/__init__.py +9 -3
- alita_sdk/tools/localgit/local_git.py +62 -54
- alita_sdk/tools/localgit/tool.py +5 -1
- alita_sdk/tools/memory/__init__.py +38 -14
- alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
- alita_sdk/tools/ocr/__init__.py +11 -8
- alita_sdk/tools/openapi/__init__.py +491 -106
- alita_sdk/tools/openapi/api_wrapper.py +1357 -0
- alita_sdk/tools/openapi/tool.py +20 -0
- alita_sdk/tools/pandas/__init__.py +20 -12
- alita_sdk/tools/pandas/api_wrapper.py +40 -45
- alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
- alita_sdk/tools/postman/__init__.py +11 -11
- alita_sdk/tools/postman/api_wrapper.py +19 -8
- alita_sdk/tools/postman/postman_analysis.py +8 -1
- alita_sdk/tools/pptx/__init__.py +11 -10
- alita_sdk/tools/qtest/__init__.py +22 -14
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +13 -10
- alita_sdk/tools/report_portal/__init__.py +23 -16
- alita_sdk/tools/salesforce/__init__.py +22 -16
- alita_sdk/tools/servicenow/__init__.py +21 -16
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +17 -14
- alita_sdk/tools/sharepoint/api_wrapper.py +179 -39
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +13 -8
- alita_sdk/tools/sql/__init__.py +22 -19
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +21 -13
- alita_sdk/tools/testrail/__init__.py +13 -11
- alita_sdk/tools/testrail/api_wrapper.py +214 -46
- alita_sdk/tools/utils/__init__.py +28 -4
- alita_sdk/tools/utils/content_parser.py +241 -55
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
- alita_sdk/tools/xray/__init__.py +18 -14
- alita_sdk/tools/xray/api_wrapper.py +58 -113
- alita_sdk/tools/yagmail/__init__.py +9 -3
- alita_sdk/tools/zephyr/__init__.py +12 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +16 -9
- alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
- alita_sdk/tools/zephyr_essential/__init__.py +16 -10
- alita_sdk/tools/zephyr_essential/api_wrapper.py +297 -54
- alita_sdk/tools/zephyr_essential/client.py +6 -4
- alita_sdk/tools/zephyr_scale/__init__.py +13 -8
- alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
- alita_sdk/tools/zephyr_squad/__init__.py +12 -7
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/METADATA +184 -37
- alita_sdk-0.3.584.dist-info/RECORD +452 -0
- alita_sdk-0.3.584.dist-info/entry_points.txt +2 -0
- alita_sdk/tools/bitbucket/tools.py +0 -304
- alita_sdk-0.3.257.dist-info/RECORD +0 -343
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Dict, Optional
|
|
3
|
+
from urllib.parse import quote
|
|
4
|
+
|
|
5
|
+
import requests
|
|
6
|
+
from typing import Any
|
|
7
|
+
from json import dumps
|
|
8
|
+
import chardet
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ApiDetailsRequestError(Exception):
|
|
14
|
+
...
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SandboxArtifact:
|
|
18
|
+
def __init__(self, client: Any, bucket_name: str):
|
|
19
|
+
self.client = client
|
|
20
|
+
self.bucket_name = bucket_name
|
|
21
|
+
if not self.client.bucket_exists(bucket_name):
|
|
22
|
+
self.client.create_bucket(bucket_name)
|
|
23
|
+
|
|
24
|
+
def create(self, artifact_name: str, artifact_data: Any, bucket_name: str = None):
|
|
25
|
+
try:
|
|
26
|
+
if not bucket_name:
|
|
27
|
+
bucket_name = self.bucket_name
|
|
28
|
+
return dumps(self.client.create_artifact(bucket_name, artifact_name, artifact_data))
|
|
29
|
+
except Exception as e:
|
|
30
|
+
logger.error(f'Error: {e}')
|
|
31
|
+
return f'Error: {e}'
|
|
32
|
+
|
|
33
|
+
def get(self,
|
|
34
|
+
artifact_name: str,
|
|
35
|
+
bucket_name: str = None,
|
|
36
|
+
is_capture_image: bool = False,
|
|
37
|
+
page_number: int = None,
|
|
38
|
+
sheet_name: str = None,
|
|
39
|
+
excel_by_sheets: bool = False,
|
|
40
|
+
llm=None):
|
|
41
|
+
if not bucket_name:
|
|
42
|
+
bucket_name = self.bucket_name
|
|
43
|
+
data = self.client.download_artifact(bucket_name, artifact_name)
|
|
44
|
+
if len(data) == 0:
|
|
45
|
+
# empty file might be created
|
|
46
|
+
return ''
|
|
47
|
+
if isinstance(data, dict) and data['error']:
|
|
48
|
+
return f'{data['error']}. {data['content'] if data['content'] else ''}'
|
|
49
|
+
detected = chardet.detect(data)
|
|
50
|
+
return data
|
|
51
|
+
|
|
52
|
+
def delete(self, artifact_name: str, bucket_name=None):
|
|
53
|
+
if not bucket_name:
|
|
54
|
+
bucket_name = self.bucket_name
|
|
55
|
+
self.client.delete_artifact(bucket_name, artifact_name)
|
|
56
|
+
|
|
57
|
+
def list(self, bucket_name: str = None, return_as_string=True) -> str | dict:
|
|
58
|
+
if not bucket_name:
|
|
59
|
+
bucket_name = self.bucket_name
|
|
60
|
+
artifacts = self.client.list_artifacts(bucket_name)
|
|
61
|
+
return str(artifacts) if return_as_string else artifacts
|
|
62
|
+
|
|
63
|
+
def append(self, artifact_name: str, additional_data: Any, bucket_name: str = None):
|
|
64
|
+
if not bucket_name:
|
|
65
|
+
bucket_name = self.bucket_name
|
|
66
|
+
data = self.get(artifact_name, bucket_name)
|
|
67
|
+
if data == 'Could not detect encoding':
|
|
68
|
+
return data
|
|
69
|
+
data += f'{additional_data}' if len(data) > 0 else additional_data
|
|
70
|
+
self.client.create_artifact(bucket_name, artifact_name, data)
|
|
71
|
+
return 'Data appended successfully'
|
|
72
|
+
|
|
73
|
+
def overwrite(self, artifact_name: str, new_data: Any, bucket_name: str = None):
|
|
74
|
+
if not bucket_name:
|
|
75
|
+
bucket_name = self.bucket_name
|
|
76
|
+
return self.create(artifact_name, new_data, bucket_name)
|
|
77
|
+
|
|
78
|
+
def get_content_bytes(self,
|
|
79
|
+
artifact_name: str,
|
|
80
|
+
bucket_name: str = None):
|
|
81
|
+
if not bucket_name:
|
|
82
|
+
bucket_name = self.bucket_name
|
|
83
|
+
return self.client.download_artifact(bucket_name, artifact_name)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SandboxClient:
|
|
87
|
+
def __init__(self,
|
|
88
|
+
base_url: str,
|
|
89
|
+
project_id: int,
|
|
90
|
+
auth_token: str,
|
|
91
|
+
api_extra_headers: Optional[dict] = None,
|
|
92
|
+
configurations: Optional[list] = None,
|
|
93
|
+
**kwargs):
|
|
94
|
+
|
|
95
|
+
self.base_url = base_url.rstrip('/')
|
|
96
|
+
self.api_path = '/api/v1'
|
|
97
|
+
self.llm_path = '/llm/v1'
|
|
98
|
+
self.project_id = project_id
|
|
99
|
+
self.auth_token = auth_token
|
|
100
|
+
self.headers = {
|
|
101
|
+
'Authorization': f'Bearer {auth_token}',
|
|
102
|
+
'X-SECRET': kwargs.get('XSECRET', 'secret')
|
|
103
|
+
}
|
|
104
|
+
if api_extra_headers is not None:
|
|
105
|
+
self.headers.update(api_extra_headers)
|
|
106
|
+
self.predict_url = f'{self.base_url}{self.api_path}/prompt_lib/predict/prompt_lib/{self.project_id}'
|
|
107
|
+
self.prompt_versions = f'{self.base_url}{self.api_path}/prompt_lib/version/prompt_lib/{self.project_id}'
|
|
108
|
+
self.prompts = f'{self.base_url}{self.api_path}/prompt_lib/prompt/prompt_lib/{self.project_id}'
|
|
109
|
+
self.datasources = f'{self.base_url}{self.api_path}/datasources/datasource/prompt_lib/{self.project_id}'
|
|
110
|
+
self.datasources_predict = f'{self.base_url}{self.api_path}/datasources/predict/prompt_lib/{self.project_id}'
|
|
111
|
+
self.datasources_search = f'{self.base_url}{self.api_path}/datasources/search/prompt_lib/{self.project_id}'
|
|
112
|
+
self.app = f'{self.base_url}{self.api_path}/applications/application/prompt_lib/{self.project_id}'
|
|
113
|
+
self.mcp_tools_list = f'{self.base_url}{self.api_path}/mcp_sse/tools_list/{self.project_id}'
|
|
114
|
+
self.mcp_tools_call = f'{self.base_url}{self.api_path}/mcp_sse/tools_call/{self.project_id}'
|
|
115
|
+
self.application_versions = f'{self.base_url}{self.api_path}/applications/version/prompt_lib/{self.project_id}'
|
|
116
|
+
self.list_apps_url = f'{self.base_url}{self.api_path}/applications/applications/prompt_lib/{self.project_id}'
|
|
117
|
+
self.integration_details = f'{self.base_url}{self.api_path}/integrations/integration/{self.project_id}'
|
|
118
|
+
self.secrets_url = f'{self.base_url}{self.api_path}/secrets/secret/{self.project_id}'
|
|
119
|
+
self.artifacts_url = f'{self.base_url}{self.api_path}/artifacts/artifacts/default/{self.project_id}'
|
|
120
|
+
self.artifact_url = f'{self.base_url}{self.api_path}/artifacts/artifact/default/{self.project_id}'
|
|
121
|
+
self.bucket_url = f'{self.base_url}{self.api_path}/artifacts/buckets/{self.project_id}'
|
|
122
|
+
self.configurations_url = f'{self.base_url}{self.api_path}/integrations/integrations/default/{self.project_id}?section=configurations&unsecret=true'
|
|
123
|
+
self.ai_section_url = f'{self.base_url}{self.api_path}/integrations/integrations/default/{self.project_id}?section=ai'
|
|
124
|
+
self.image_generation_url = f'{self.base_url}{self.llm_path}/images/generations'
|
|
125
|
+
self.auth_user_url = f'{self.base_url}{self.api_path}/auth/user'
|
|
126
|
+
self.configurations: list = configurations or []
|
|
127
|
+
self.model_timeout = kwargs.get('model_timeout', 120)
|
|
128
|
+
self.model_image_generation = kwargs.get('model_image_generation')
|
|
129
|
+
|
|
130
|
+
def get_mcp_toolkits(self):
|
|
131
|
+
if user_id := self._get_real_user_id():
|
|
132
|
+
url = f'{self.mcp_tools_list}/{user_id}'
|
|
133
|
+
data = requests.get(url, headers=self.headers, verify=False).json()
|
|
134
|
+
return data
|
|
135
|
+
else:
|
|
136
|
+
return []
|
|
137
|
+
|
|
138
|
+
def mcp_tool_call(self, params: dict[str, Any]):
|
|
139
|
+
if user_id := self._get_real_user_id():
|
|
140
|
+
url = f'{self.mcp_tools_call}/{user_id}'
|
|
141
|
+
#
|
|
142
|
+
# This loop iterates over each key-value pair in the arguments dictionary,
|
|
143
|
+
# and if a value is a Pydantic object, it replaces it with its dictionary representation using .dict().
|
|
144
|
+
for arg_name, arg_value in params.get('params', {}).get('arguments', {}).items():
|
|
145
|
+
if isinstance(arg_value, list):
|
|
146
|
+
params['params']['arguments'][arg_name] = [
|
|
147
|
+
item.dict() if hasattr(item, 'dict') and callable(item.dict) else item
|
|
148
|
+
for item in arg_value
|
|
149
|
+
]
|
|
150
|
+
elif hasattr(arg_value, 'dict') and callable(arg_value.dict):
|
|
151
|
+
params['params']['arguments'][arg_name] = arg_value.dict()
|
|
152
|
+
#
|
|
153
|
+
response = requests.post(url, headers=self.headers, json=params, verify=False)
|
|
154
|
+
try:
|
|
155
|
+
return response.json()
|
|
156
|
+
except (ValueError, TypeError):
|
|
157
|
+
return response.text
|
|
158
|
+
else:
|
|
159
|
+
return f'Error: Could not determine user ID for MCP tool call'
|
|
160
|
+
|
|
161
|
+
def get_app_details(self, application_id: int):
|
|
162
|
+
url = f'{self.app}/{application_id}'
|
|
163
|
+
data = requests.get(url, headers=self.headers, verify=False).json()
|
|
164
|
+
return data
|
|
165
|
+
|
|
166
|
+
def get_list_of_apps(self):
|
|
167
|
+
apps = []
|
|
168
|
+
limit = 10
|
|
169
|
+
offset = 0
|
|
170
|
+
total_count = None
|
|
171
|
+
|
|
172
|
+
while total_count is None or offset < total_count:
|
|
173
|
+
params = {'offset': offset, 'limit': limit}
|
|
174
|
+
resp = requests.get(self.list_apps_url, headers=self.headers, params=params, verify=False)
|
|
175
|
+
|
|
176
|
+
if resp.ok:
|
|
177
|
+
data = resp.json()
|
|
178
|
+
total_count = data.get('total')
|
|
179
|
+
apps.extend([{'name': app['name'], 'id': app['id']} for app in data.get('rows', [])])
|
|
180
|
+
offset += limit
|
|
181
|
+
else:
|
|
182
|
+
break
|
|
183
|
+
|
|
184
|
+
return apps
|
|
185
|
+
|
|
186
|
+
def fetch_available_configurations(self) -> list:
|
|
187
|
+
resp = requests.get(self.configurations_url, headers=self.headers, verify=False)
|
|
188
|
+
if resp.ok:
|
|
189
|
+
return resp.json()
|
|
190
|
+
return []
|
|
191
|
+
|
|
192
|
+
def all_models_and_integrations(self):
|
|
193
|
+
resp = requests.get(self.ai_section_url, headers=self.headers, verify=False)
|
|
194
|
+
if resp.ok:
|
|
195
|
+
return resp.json()
|
|
196
|
+
return []
|
|
197
|
+
|
|
198
|
+
def generate_image(self,
|
|
199
|
+
prompt: str,
|
|
200
|
+
n: int = 1,
|
|
201
|
+
size: str = 'auto',
|
|
202
|
+
quality: str = 'auto',
|
|
203
|
+
response_format: str = 'b64_json',
|
|
204
|
+
style: Optional[str] = None) -> dict:
|
|
205
|
+
|
|
206
|
+
if not self.model_image_generation:
|
|
207
|
+
raise ValueError('Image generation model is not configured for this client')
|
|
208
|
+
|
|
209
|
+
image_generation_data = {
|
|
210
|
+
'prompt': prompt,
|
|
211
|
+
'model': self.model_image_generation,
|
|
212
|
+
'n': n,
|
|
213
|
+
'response_format': response_format,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
# Only add optional parameters if they have meaningful values
|
|
217
|
+
if size and size.lower() != 'auto':
|
|
218
|
+
image_generation_data['size'] = size
|
|
219
|
+
|
|
220
|
+
if quality and quality.lower() != 'auto':
|
|
221
|
+
image_generation_data['quality'] = quality
|
|
222
|
+
|
|
223
|
+
if style:
|
|
224
|
+
image_generation_data['style'] = style
|
|
225
|
+
|
|
226
|
+
# Standard headers for image generation
|
|
227
|
+
image_headers = self.headers.copy()
|
|
228
|
+
image_headers.update({
|
|
229
|
+
'Content-Type': 'application/json',
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
logger.info(f'Generating image with model: {self.model_image_generation}, prompt: {prompt[:50]}...')
|
|
233
|
+
|
|
234
|
+
try:
|
|
235
|
+
response = requests.post(
|
|
236
|
+
self.image_generation_url,
|
|
237
|
+
headers=image_headers,
|
|
238
|
+
json=image_generation_data,
|
|
239
|
+
verify=False,
|
|
240
|
+
timeout=self.model_timeout
|
|
241
|
+
)
|
|
242
|
+
response.raise_for_status()
|
|
243
|
+
return response.json()
|
|
244
|
+
|
|
245
|
+
except requests.exceptions.HTTPError as e:
|
|
246
|
+
logger.error(f'Image generation failed: {e.response.status_code} - {e.response.text}')
|
|
247
|
+
raise
|
|
248
|
+
except requests.exceptions.RequestException as e:
|
|
249
|
+
logger.error(f'Image generation request failed: {e}')
|
|
250
|
+
raise
|
|
251
|
+
|
|
252
|
+
def get_app_version_details(self, application_id: int, application_version_id: int) -> dict:
|
|
253
|
+
url = f'{self.application_versions}/{application_id}/{application_version_id}'
|
|
254
|
+
if self.configurations:
|
|
255
|
+
configs = self.configurations
|
|
256
|
+
else:
|
|
257
|
+
configs = self.fetch_available_configurations()
|
|
258
|
+
|
|
259
|
+
resp = requests.patch(url, headers=self.headers, verify=False, json={'configurations': configs})
|
|
260
|
+
if resp.ok:
|
|
261
|
+
return resp.json()
|
|
262
|
+
logger.error(f'Failed to fetch application version details: {resp.status_code} - {resp.text}.'
|
|
263
|
+
f' Application ID: {application_id}, Version ID: {application_version_id}')
|
|
264
|
+
raise ApiDetailsRequestError(
|
|
265
|
+
f'Failed to fetch application version details for {application_id}/{application_version_id}.')
|
|
266
|
+
|
|
267
|
+
def get_integration_details(self, integration_id: str, format_for_model: bool = False):
|
|
268
|
+
url = f'{self.integration_details}/{integration_id}'
|
|
269
|
+
data = requests.get(url, headers=self.headers, verify=False).json()
|
|
270
|
+
return data
|
|
271
|
+
|
|
272
|
+
def unsecret(self, secret_name: str):
|
|
273
|
+
url = f'{self.secrets_url}/{secret_name}'
|
|
274
|
+
data = requests.get(url, headers=self.headers, verify=False).json()
|
|
275
|
+
logger.info(f'Unsecret response: {data}')
|
|
276
|
+
return data.get('value', None)
|
|
277
|
+
|
|
278
|
+
def artifact(self, bucket_name):
|
|
279
|
+
return SandboxArtifact(self, bucket_name)
|
|
280
|
+
|
|
281
|
+
def _process_requst(self, data: requests.Response) -> Dict[str, str]:
|
|
282
|
+
if data.status_code == 403:
|
|
283
|
+
return {'error': 'You are not authorized to access this resource'}
|
|
284
|
+
elif data.status_code == 404:
|
|
285
|
+
return {'error': 'Resource not found'}
|
|
286
|
+
elif data.status_code != 200:
|
|
287
|
+
return {
|
|
288
|
+
'error': 'An error occurred while fetching the resource',
|
|
289
|
+
'content': data.text
|
|
290
|
+
}
|
|
291
|
+
else:
|
|
292
|
+
return data.json()
|
|
293
|
+
|
|
294
|
+
def bucket_exists(self, bucket_name):
|
|
295
|
+
try:
|
|
296
|
+
resp = self._process_requst(
|
|
297
|
+
requests.get(f'{self.bucket_url}', headers=self.headers, verify=False)
|
|
298
|
+
)
|
|
299
|
+
for each in resp.get('rows', []):
|
|
300
|
+
if each['name'] == bucket_name:
|
|
301
|
+
return True
|
|
302
|
+
return False
|
|
303
|
+
except:
|
|
304
|
+
return False
|
|
305
|
+
|
|
306
|
+
def create_bucket(self, bucket_name, expiration_measure='months', expiration_value=1):
|
|
307
|
+
post_data = {
|
|
308
|
+
'name': bucket_name,
|
|
309
|
+
'expiration_measure': expiration_measure,
|
|
310
|
+
'expiration_value': expiration_value
|
|
311
|
+
}
|
|
312
|
+
resp = requests.post(f'{self.bucket_url}', headers=self.headers, json=post_data, verify=False)
|
|
313
|
+
return self._process_requst(resp)
|
|
314
|
+
|
|
315
|
+
def list_artifacts(self, bucket_name: str):
|
|
316
|
+
# Ensure bucket name is lowercase as required by the API
|
|
317
|
+
url = f'{self.artifacts_url}/{bucket_name.lower()}'
|
|
318
|
+
data = requests.get(url, headers=self.headers, verify=False)
|
|
319
|
+
return self._process_requst(data)
|
|
320
|
+
|
|
321
|
+
def create_artifact(self, bucket_name, artifact_name, artifact_data):
|
|
322
|
+
url = f'{self.artifacts_url}/{bucket_name.lower()}'
|
|
323
|
+
data = requests.post(url, headers=self.headers, files={
|
|
324
|
+
'file': (artifact_name, artifact_data)
|
|
325
|
+
}, verify=False)
|
|
326
|
+
return self._process_requst(data)
|
|
327
|
+
|
|
328
|
+
def download_artifact(self, bucket_name, artifact_name):
|
|
329
|
+
url = f'{self.artifact_url}/{bucket_name.lower()}/{artifact_name}'
|
|
330
|
+
data = requests.get(url, headers=self.headers, verify=False)
|
|
331
|
+
if data.status_code == 403:
|
|
332
|
+
return {'error': 'You are not authorized to access this resource'}
|
|
333
|
+
elif data.status_code == 404:
|
|
334
|
+
return {'error': 'Resource not found'}
|
|
335
|
+
elif data.status_code != 200:
|
|
336
|
+
return {
|
|
337
|
+
'error': 'An error occurred while fetching the resource',
|
|
338
|
+
'content': data.content
|
|
339
|
+
}
|
|
340
|
+
return data.content
|
|
341
|
+
|
|
342
|
+
def delete_artifact(self, bucket_name, artifact_name):
|
|
343
|
+
url = f'{self.artifact_url}/{bucket_name}'
|
|
344
|
+
data = requests.delete(url, headers=self.headers, verify=False, params={'filename': quote(artifact_name)})
|
|
345
|
+
return self._process_requst(data)
|
|
346
|
+
|
|
347
|
+
def get_user_data(self) -> Dict[str, Any]:
|
|
348
|
+
resp = requests.get(self.auth_user_url, headers=self.headers, verify=False)
|
|
349
|
+
if resp.ok:
|
|
350
|
+
return resp.json()
|
|
351
|
+
logger.error(f'Failed to fetch user data: {resp.status_code} - {resp.text}')
|
|
352
|
+
raise ApiDetailsRequestError(f'Failed to fetch user data with status code {resp.status_code}.')
|