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.

Files changed (281) hide show
  1. alita_sdk/cli/__init__.py +10 -0
  2. alita_sdk/cli/__main__.py +17 -0
  3. alita_sdk/cli/agent/__init__.py +5 -0
  4. alita_sdk/cli/agent/default.py +258 -0
  5. alita_sdk/cli/agent_executor.py +155 -0
  6. alita_sdk/cli/agent_loader.py +215 -0
  7. alita_sdk/cli/agent_ui.py +228 -0
  8. alita_sdk/cli/agents.py +3794 -0
  9. alita_sdk/cli/callbacks.py +647 -0
  10. alita_sdk/cli/cli.py +168 -0
  11. alita_sdk/cli/config.py +306 -0
  12. alita_sdk/cli/context/__init__.py +30 -0
  13. alita_sdk/cli/context/cleanup.py +198 -0
  14. alita_sdk/cli/context/manager.py +731 -0
  15. alita_sdk/cli/context/message.py +285 -0
  16. alita_sdk/cli/context/strategies.py +289 -0
  17. alita_sdk/cli/context/token_estimation.py +127 -0
  18. alita_sdk/cli/formatting.py +182 -0
  19. alita_sdk/cli/input_handler.py +419 -0
  20. alita_sdk/cli/inventory.py +1073 -0
  21. alita_sdk/cli/mcp_loader.py +315 -0
  22. alita_sdk/cli/toolkit.py +327 -0
  23. alita_sdk/cli/toolkit_loader.py +85 -0
  24. alita_sdk/cli/tools/__init__.py +43 -0
  25. alita_sdk/cli/tools/approval.py +224 -0
  26. alita_sdk/cli/tools/filesystem.py +1751 -0
  27. alita_sdk/cli/tools/planning.py +389 -0
  28. alita_sdk/cli/tools/terminal.py +414 -0
  29. alita_sdk/community/__init__.py +72 -12
  30. alita_sdk/community/inventory/__init__.py +236 -0
  31. alita_sdk/community/inventory/config.py +257 -0
  32. alita_sdk/community/inventory/enrichment.py +2137 -0
  33. alita_sdk/community/inventory/extractors.py +1469 -0
  34. alita_sdk/community/inventory/ingestion.py +3172 -0
  35. alita_sdk/community/inventory/knowledge_graph.py +1457 -0
  36. alita_sdk/community/inventory/parsers/__init__.py +218 -0
  37. alita_sdk/community/inventory/parsers/base.py +295 -0
  38. alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
  39. alita_sdk/community/inventory/parsers/go_parser.py +851 -0
  40. alita_sdk/community/inventory/parsers/html_parser.py +389 -0
  41. alita_sdk/community/inventory/parsers/java_parser.py +593 -0
  42. alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
  43. alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
  44. alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
  45. alita_sdk/community/inventory/parsers/python_parser.py +604 -0
  46. alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
  47. alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
  48. alita_sdk/community/inventory/parsers/text_parser.py +322 -0
  49. alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
  50. alita_sdk/community/inventory/patterns/__init__.py +61 -0
  51. alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
  52. alita_sdk/community/inventory/patterns/loader.py +348 -0
  53. alita_sdk/community/inventory/patterns/registry.py +198 -0
  54. alita_sdk/community/inventory/presets.py +535 -0
  55. alita_sdk/community/inventory/retrieval.py +1403 -0
  56. alita_sdk/community/inventory/toolkit.py +173 -0
  57. alita_sdk/community/inventory/toolkit_utils.py +176 -0
  58. alita_sdk/community/inventory/visualize.py +1370 -0
  59. alita_sdk/configurations/__init__.py +11 -0
  60. alita_sdk/configurations/ado.py +148 -2
  61. alita_sdk/configurations/azure_search.py +1 -1
  62. alita_sdk/configurations/bigquery.py +1 -1
  63. alita_sdk/configurations/bitbucket.py +94 -2
  64. alita_sdk/configurations/browser.py +18 -0
  65. alita_sdk/configurations/carrier.py +19 -0
  66. alita_sdk/configurations/confluence.py +130 -1
  67. alita_sdk/configurations/delta_lake.py +1 -1
  68. alita_sdk/configurations/figma.py +76 -5
  69. alita_sdk/configurations/github.py +65 -1
  70. alita_sdk/configurations/gitlab.py +81 -0
  71. alita_sdk/configurations/google_places.py +17 -0
  72. alita_sdk/configurations/jira.py +103 -0
  73. alita_sdk/configurations/openapi.py +323 -0
  74. alita_sdk/configurations/postman.py +1 -1
  75. alita_sdk/configurations/qtest.py +72 -3
  76. alita_sdk/configurations/report_portal.py +115 -0
  77. alita_sdk/configurations/salesforce.py +19 -0
  78. alita_sdk/configurations/service_now.py +1 -12
  79. alita_sdk/configurations/sharepoint.py +167 -0
  80. alita_sdk/configurations/sonar.py +18 -0
  81. alita_sdk/configurations/sql.py +20 -0
  82. alita_sdk/configurations/testio.py +101 -0
  83. alita_sdk/configurations/testrail.py +88 -0
  84. alita_sdk/configurations/xray.py +94 -1
  85. alita_sdk/configurations/zephyr_enterprise.py +94 -1
  86. alita_sdk/configurations/zephyr_essential.py +95 -0
  87. alita_sdk/runtime/clients/artifact.py +21 -4
  88. alita_sdk/runtime/clients/client.py +458 -67
  89. alita_sdk/runtime/clients/mcp_discovery.py +342 -0
  90. alita_sdk/runtime/clients/mcp_manager.py +262 -0
  91. alita_sdk/runtime/clients/sandbox_client.py +352 -0
  92. alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
  93. alita_sdk/runtime/langchain/assistant.py +183 -43
  94. alita_sdk/runtime/langchain/constants.py +647 -1
  95. alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
  96. alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +209 -31
  97. alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +1 -1
  98. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
  99. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -3
  100. alita_sdk/runtime/langchain/document_loaders/AlitaMarkdownLoader.py +66 -0
  101. alita_sdk/runtime/langchain/document_loaders/AlitaPDFLoader.py +79 -10
  102. alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +52 -15
  103. alita_sdk/runtime/langchain/document_loaders/AlitaPythonLoader.py +9 -0
  104. alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -4
  105. alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +15 -2
  106. alita_sdk/runtime/langchain/document_loaders/ImageParser.py +30 -0
  107. alita_sdk/runtime/langchain/document_loaders/constants.py +189 -41
  108. alita_sdk/runtime/langchain/interfaces/llm_processor.py +4 -2
  109. alita_sdk/runtime/langchain/langraph_agent.py +493 -105
  110. alita_sdk/runtime/langchain/utils.py +118 -8
  111. alita_sdk/runtime/llms/preloaded.py +2 -6
  112. alita_sdk/runtime/models/mcp_models.py +61 -0
  113. alita_sdk/runtime/skills/__init__.py +91 -0
  114. alita_sdk/runtime/skills/callbacks.py +498 -0
  115. alita_sdk/runtime/skills/discovery.py +540 -0
  116. alita_sdk/runtime/skills/executor.py +610 -0
  117. alita_sdk/runtime/skills/input_builder.py +371 -0
  118. alita_sdk/runtime/skills/models.py +330 -0
  119. alita_sdk/runtime/skills/registry.py +355 -0
  120. alita_sdk/runtime/skills/skill_runner.py +330 -0
  121. alita_sdk/runtime/toolkits/__init__.py +28 -0
  122. alita_sdk/runtime/toolkits/application.py +14 -4
  123. alita_sdk/runtime/toolkits/artifact.py +25 -9
  124. alita_sdk/runtime/toolkits/datasource.py +13 -6
  125. alita_sdk/runtime/toolkits/mcp.py +782 -0
  126. alita_sdk/runtime/toolkits/planning.py +178 -0
  127. alita_sdk/runtime/toolkits/skill_router.py +238 -0
  128. alita_sdk/runtime/toolkits/subgraph.py +11 -6
  129. alita_sdk/runtime/toolkits/tools.py +314 -70
  130. alita_sdk/runtime/toolkits/vectorstore.py +11 -5
  131. alita_sdk/runtime/tools/__init__.py +24 -0
  132. alita_sdk/runtime/tools/application.py +16 -4
  133. alita_sdk/runtime/tools/artifact.py +367 -33
  134. alita_sdk/runtime/tools/data_analysis.py +183 -0
  135. alita_sdk/runtime/tools/function.py +100 -4
  136. alita_sdk/runtime/tools/graph.py +81 -0
  137. alita_sdk/runtime/tools/image_generation.py +218 -0
  138. alita_sdk/runtime/tools/llm.py +1032 -177
  139. alita_sdk/runtime/tools/loop.py +3 -1
  140. alita_sdk/runtime/tools/loop_output.py +3 -1
  141. alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
  142. alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
  143. alita_sdk/runtime/tools/mcp_server_tool.py +3 -1
  144. alita_sdk/runtime/tools/planning/__init__.py +36 -0
  145. alita_sdk/runtime/tools/planning/models.py +246 -0
  146. alita_sdk/runtime/tools/planning/wrapper.py +607 -0
  147. alita_sdk/runtime/tools/router.py +2 -1
  148. alita_sdk/runtime/tools/sandbox.py +375 -0
  149. alita_sdk/runtime/tools/skill_router.py +776 -0
  150. alita_sdk/runtime/tools/tool.py +3 -1
  151. alita_sdk/runtime/tools/vectorstore.py +69 -65
  152. alita_sdk/runtime/tools/vectorstore_base.py +163 -90
  153. alita_sdk/runtime/utils/AlitaCallback.py +137 -21
  154. alita_sdk/runtime/utils/constants.py +5 -1
  155. alita_sdk/runtime/utils/mcp_client.py +492 -0
  156. alita_sdk/runtime/utils/mcp_oauth.py +361 -0
  157. alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
  158. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  159. alita_sdk/runtime/utils/streamlit.py +41 -14
  160. alita_sdk/runtime/utils/toolkit_utils.py +28 -9
  161. alita_sdk/runtime/utils/utils.py +48 -0
  162. alita_sdk/tools/__init__.py +135 -37
  163. alita_sdk/tools/ado/__init__.py +2 -2
  164. alita_sdk/tools/ado/repos/__init__.py +16 -19
  165. alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
  166. alita_sdk/tools/ado/test_plan/__init__.py +27 -8
  167. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
  168. alita_sdk/tools/ado/wiki/__init__.py +28 -12
  169. alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
  170. alita_sdk/tools/ado/work_item/__init__.py +28 -12
  171. alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
  172. alita_sdk/tools/advanced_jira_mining/__init__.py +13 -8
  173. alita_sdk/tools/aws/delta_lake/__init__.py +15 -11
  174. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  175. alita_sdk/tools/azure_ai/search/__init__.py +14 -8
  176. alita_sdk/tools/base/tool.py +5 -1
  177. alita_sdk/tools/base_indexer_toolkit.py +454 -110
  178. alita_sdk/tools/bitbucket/__init__.py +28 -19
  179. alita_sdk/tools/bitbucket/api_wrapper.py +285 -27
  180. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
  181. alita_sdk/tools/browser/__init__.py +41 -16
  182. alita_sdk/tools/browser/crawler.py +3 -1
  183. alita_sdk/tools/browser/utils.py +15 -6
  184. alita_sdk/tools/carrier/__init__.py +18 -17
  185. alita_sdk/tools/carrier/backend_reports_tool.py +8 -4
  186. alita_sdk/tools/carrier/excel_reporter.py +8 -4
  187. alita_sdk/tools/chunkers/__init__.py +3 -1
  188. alita_sdk/tools/chunkers/code/codeparser.py +1 -1
  189. alita_sdk/tools/chunkers/sematic/json_chunker.py +2 -1
  190. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  191. alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
  192. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  193. alita_sdk/tools/cloud/aws/__init__.py +12 -7
  194. alita_sdk/tools/cloud/azure/__init__.py +12 -7
  195. alita_sdk/tools/cloud/gcp/__init__.py +12 -7
  196. alita_sdk/tools/cloud/k8s/__init__.py +12 -7
  197. alita_sdk/tools/code/linter/__init__.py +10 -8
  198. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  199. alita_sdk/tools/code/sonar/__init__.py +21 -13
  200. alita_sdk/tools/code_indexer_toolkit.py +199 -0
  201. alita_sdk/tools/confluence/__init__.py +22 -14
  202. alita_sdk/tools/confluence/api_wrapper.py +197 -58
  203. alita_sdk/tools/confluence/loader.py +14 -2
  204. alita_sdk/tools/custom_open_api/__init__.py +12 -5
  205. alita_sdk/tools/elastic/__init__.py +11 -8
  206. alita_sdk/tools/elitea_base.py +546 -64
  207. alita_sdk/tools/figma/__init__.py +60 -11
  208. alita_sdk/tools/figma/api_wrapper.py +1400 -167
  209. alita_sdk/tools/figma/figma_client.py +73 -0
  210. alita_sdk/tools/figma/toon_tools.py +2748 -0
  211. alita_sdk/tools/github/__init__.py +18 -17
  212. alita_sdk/tools/github/api_wrapper.py +9 -26
  213. alita_sdk/tools/github/github_client.py +81 -12
  214. alita_sdk/tools/github/schemas.py +2 -1
  215. alita_sdk/tools/github/tool.py +5 -1
  216. alita_sdk/tools/gitlab/__init__.py +19 -13
  217. alita_sdk/tools/gitlab/api_wrapper.py +256 -80
  218. alita_sdk/tools/gitlab_org/__init__.py +14 -10
  219. alita_sdk/tools/google/bigquery/__init__.py +14 -13
  220. alita_sdk/tools/google/bigquery/tool.py +5 -1
  221. alita_sdk/tools/google_places/__init__.py +21 -11
  222. alita_sdk/tools/jira/__init__.py +22 -11
  223. alita_sdk/tools/jira/api_wrapper.py +315 -168
  224. alita_sdk/tools/keycloak/__init__.py +11 -8
  225. alita_sdk/tools/localgit/__init__.py +9 -3
  226. alita_sdk/tools/localgit/local_git.py +62 -54
  227. alita_sdk/tools/localgit/tool.py +5 -1
  228. alita_sdk/tools/memory/__init__.py +38 -14
  229. alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
  230. alita_sdk/tools/ocr/__init__.py +11 -8
  231. alita_sdk/tools/openapi/__init__.py +491 -106
  232. alita_sdk/tools/openapi/api_wrapper.py +1357 -0
  233. alita_sdk/tools/openapi/tool.py +20 -0
  234. alita_sdk/tools/pandas/__init__.py +20 -12
  235. alita_sdk/tools/pandas/api_wrapper.py +40 -45
  236. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  237. alita_sdk/tools/postman/__init__.py +11 -11
  238. alita_sdk/tools/postman/api_wrapper.py +19 -8
  239. alita_sdk/tools/postman/postman_analysis.py +8 -1
  240. alita_sdk/tools/pptx/__init__.py +11 -10
  241. alita_sdk/tools/qtest/__init__.py +22 -14
  242. alita_sdk/tools/qtest/api_wrapper.py +1784 -88
  243. alita_sdk/tools/rally/__init__.py +13 -10
  244. alita_sdk/tools/report_portal/__init__.py +23 -16
  245. alita_sdk/tools/salesforce/__init__.py +22 -16
  246. alita_sdk/tools/servicenow/__init__.py +21 -16
  247. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  248. alita_sdk/tools/sharepoint/__init__.py +17 -14
  249. alita_sdk/tools/sharepoint/api_wrapper.py +179 -39
  250. alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
  251. alita_sdk/tools/sharepoint/utils.py +8 -2
  252. alita_sdk/tools/slack/__init__.py +13 -8
  253. alita_sdk/tools/sql/__init__.py +22 -19
  254. alita_sdk/tools/sql/api_wrapper.py +71 -23
  255. alita_sdk/tools/testio/__init__.py +21 -13
  256. alita_sdk/tools/testrail/__init__.py +13 -11
  257. alita_sdk/tools/testrail/api_wrapper.py +214 -46
  258. alita_sdk/tools/utils/__init__.py +28 -4
  259. alita_sdk/tools/utils/content_parser.py +241 -55
  260. alita_sdk/tools/utils/text_operations.py +254 -0
  261. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
  262. alita_sdk/tools/xray/__init__.py +18 -14
  263. alita_sdk/tools/xray/api_wrapper.py +58 -113
  264. alita_sdk/tools/yagmail/__init__.py +9 -3
  265. alita_sdk/tools/zephyr/__init__.py +12 -7
  266. alita_sdk/tools/zephyr_enterprise/__init__.py +16 -9
  267. alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
  268. alita_sdk/tools/zephyr_essential/__init__.py +16 -10
  269. alita_sdk/tools/zephyr_essential/api_wrapper.py +297 -54
  270. alita_sdk/tools/zephyr_essential/client.py +6 -4
  271. alita_sdk/tools/zephyr_scale/__init__.py +13 -8
  272. alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
  273. alita_sdk/tools/zephyr_squad/__init__.py +12 -7
  274. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/METADATA +184 -37
  275. alita_sdk-0.3.584.dist-info/RECORD +452 -0
  276. alita_sdk-0.3.584.dist-info/entry_points.txt +2 -0
  277. alita_sdk/tools/bitbucket/tools.py +0 -304
  278. alita_sdk-0.3.257.dist-info/RECORD +0 -343
  279. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/WHEEL +0 -0
  280. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/licenses/LICENSE +0 -0
  281. {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}.')