alita-sdk 0.3.379__py3-none-any.whl → 0.3.627__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.
Files changed (278) 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 +156 -0
  6. alita_sdk/cli/agent_loader.py +245 -0
  7. alita_sdk/cli/agent_ui.py +228 -0
  8. alita_sdk/cli/agents.py +3113 -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/testcases/__init__.py +94 -0
  23. alita_sdk/cli/testcases/data_generation.py +119 -0
  24. alita_sdk/cli/testcases/discovery.py +96 -0
  25. alita_sdk/cli/testcases/executor.py +84 -0
  26. alita_sdk/cli/testcases/logger.py +85 -0
  27. alita_sdk/cli/testcases/parser.py +172 -0
  28. alita_sdk/cli/testcases/prompts.py +91 -0
  29. alita_sdk/cli/testcases/reporting.py +125 -0
  30. alita_sdk/cli/testcases/setup.py +108 -0
  31. alita_sdk/cli/testcases/test_runner.py +282 -0
  32. alita_sdk/cli/testcases/utils.py +39 -0
  33. alita_sdk/cli/testcases/validation.py +90 -0
  34. alita_sdk/cli/testcases/workflow.py +196 -0
  35. alita_sdk/cli/toolkit.py +327 -0
  36. alita_sdk/cli/toolkit_loader.py +85 -0
  37. alita_sdk/cli/tools/__init__.py +43 -0
  38. alita_sdk/cli/tools/approval.py +224 -0
  39. alita_sdk/cli/tools/filesystem.py +1751 -0
  40. alita_sdk/cli/tools/planning.py +389 -0
  41. alita_sdk/cli/tools/terminal.py +414 -0
  42. alita_sdk/community/__init__.py +72 -12
  43. alita_sdk/community/inventory/__init__.py +236 -0
  44. alita_sdk/community/inventory/config.py +257 -0
  45. alita_sdk/community/inventory/enrichment.py +2137 -0
  46. alita_sdk/community/inventory/extractors.py +1469 -0
  47. alita_sdk/community/inventory/ingestion.py +3172 -0
  48. alita_sdk/community/inventory/knowledge_graph.py +1457 -0
  49. alita_sdk/community/inventory/parsers/__init__.py +218 -0
  50. alita_sdk/community/inventory/parsers/base.py +295 -0
  51. alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
  52. alita_sdk/community/inventory/parsers/go_parser.py +851 -0
  53. alita_sdk/community/inventory/parsers/html_parser.py +389 -0
  54. alita_sdk/community/inventory/parsers/java_parser.py +593 -0
  55. alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
  56. alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
  57. alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
  58. alita_sdk/community/inventory/parsers/python_parser.py +604 -0
  59. alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
  60. alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
  61. alita_sdk/community/inventory/parsers/text_parser.py +322 -0
  62. alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
  63. alita_sdk/community/inventory/patterns/__init__.py +61 -0
  64. alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
  65. alita_sdk/community/inventory/patterns/loader.py +348 -0
  66. alita_sdk/community/inventory/patterns/registry.py +198 -0
  67. alita_sdk/community/inventory/presets.py +535 -0
  68. alita_sdk/community/inventory/retrieval.py +1403 -0
  69. alita_sdk/community/inventory/toolkit.py +173 -0
  70. alita_sdk/community/inventory/toolkit_utils.py +176 -0
  71. alita_sdk/community/inventory/visualize.py +1370 -0
  72. alita_sdk/configurations/__init__.py +1 -1
  73. alita_sdk/configurations/ado.py +141 -20
  74. alita_sdk/configurations/bitbucket.py +94 -2
  75. alita_sdk/configurations/confluence.py +130 -1
  76. alita_sdk/configurations/figma.py +76 -0
  77. alita_sdk/configurations/gitlab.py +91 -0
  78. alita_sdk/configurations/jira.py +103 -0
  79. alita_sdk/configurations/openapi.py +329 -0
  80. alita_sdk/configurations/qtest.py +72 -1
  81. alita_sdk/configurations/report_portal.py +96 -0
  82. alita_sdk/configurations/sharepoint.py +148 -0
  83. alita_sdk/configurations/testio.py +83 -0
  84. alita_sdk/configurations/testrail.py +88 -0
  85. alita_sdk/configurations/xray.py +93 -0
  86. alita_sdk/configurations/zephyr_enterprise.py +93 -0
  87. alita_sdk/configurations/zephyr_essential.py +75 -0
  88. alita_sdk/runtime/clients/artifact.py +3 -3
  89. alita_sdk/runtime/clients/client.py +388 -46
  90. alita_sdk/runtime/clients/mcp_discovery.py +342 -0
  91. alita_sdk/runtime/clients/mcp_manager.py +262 -0
  92. alita_sdk/runtime/clients/sandbox_client.py +8 -21
  93. alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
  94. alita_sdk/runtime/langchain/assistant.py +157 -39
  95. alita_sdk/runtime/langchain/constants.py +647 -1
  96. alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
  97. alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
  98. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
  99. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -4
  100. alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +226 -7
  101. alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +5 -2
  102. alita_sdk/runtime/langchain/document_loaders/constants.py +40 -19
  103. alita_sdk/runtime/langchain/langraph_agent.py +405 -84
  104. alita_sdk/runtime/langchain/utils.py +106 -7
  105. alita_sdk/runtime/llms/preloaded.py +2 -6
  106. alita_sdk/runtime/models/mcp_models.py +61 -0
  107. alita_sdk/runtime/skills/__init__.py +91 -0
  108. alita_sdk/runtime/skills/callbacks.py +498 -0
  109. alita_sdk/runtime/skills/discovery.py +540 -0
  110. alita_sdk/runtime/skills/executor.py +610 -0
  111. alita_sdk/runtime/skills/input_builder.py +371 -0
  112. alita_sdk/runtime/skills/models.py +330 -0
  113. alita_sdk/runtime/skills/registry.py +355 -0
  114. alita_sdk/runtime/skills/skill_runner.py +330 -0
  115. alita_sdk/runtime/toolkits/__init__.py +31 -0
  116. alita_sdk/runtime/toolkits/application.py +29 -10
  117. alita_sdk/runtime/toolkits/artifact.py +20 -11
  118. alita_sdk/runtime/toolkits/datasource.py +13 -6
  119. alita_sdk/runtime/toolkits/mcp.py +783 -0
  120. alita_sdk/runtime/toolkits/mcp_config.py +1048 -0
  121. alita_sdk/runtime/toolkits/planning.py +178 -0
  122. alita_sdk/runtime/toolkits/skill_router.py +238 -0
  123. alita_sdk/runtime/toolkits/subgraph.py +251 -6
  124. alita_sdk/runtime/toolkits/tools.py +356 -69
  125. alita_sdk/runtime/toolkits/vectorstore.py +11 -5
  126. alita_sdk/runtime/tools/__init__.py +10 -3
  127. alita_sdk/runtime/tools/application.py +27 -6
  128. alita_sdk/runtime/tools/artifact.py +511 -28
  129. alita_sdk/runtime/tools/data_analysis.py +183 -0
  130. alita_sdk/runtime/tools/function.py +67 -35
  131. alita_sdk/runtime/tools/graph.py +10 -4
  132. alita_sdk/runtime/tools/image_generation.py +148 -46
  133. alita_sdk/runtime/tools/llm.py +1003 -128
  134. alita_sdk/runtime/tools/loop.py +3 -1
  135. alita_sdk/runtime/tools/loop_output.py +3 -1
  136. alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
  137. alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
  138. alita_sdk/runtime/tools/mcp_server_tool.py +8 -5
  139. alita_sdk/runtime/tools/planning/__init__.py +36 -0
  140. alita_sdk/runtime/tools/planning/models.py +246 -0
  141. alita_sdk/runtime/tools/planning/wrapper.py +607 -0
  142. alita_sdk/runtime/tools/router.py +2 -4
  143. alita_sdk/runtime/tools/sandbox.py +65 -48
  144. alita_sdk/runtime/tools/skill_router.py +776 -0
  145. alita_sdk/runtime/tools/tool.py +3 -1
  146. alita_sdk/runtime/tools/vectorstore.py +9 -3
  147. alita_sdk/runtime/tools/vectorstore_base.py +70 -14
  148. alita_sdk/runtime/utils/AlitaCallback.py +137 -21
  149. alita_sdk/runtime/utils/constants.py +5 -1
  150. alita_sdk/runtime/utils/mcp_client.py +492 -0
  151. alita_sdk/runtime/utils/mcp_oauth.py +361 -0
  152. alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
  153. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  154. alita_sdk/runtime/utils/serialization.py +155 -0
  155. alita_sdk/runtime/utils/streamlit.py +40 -13
  156. alita_sdk/runtime/utils/toolkit_utils.py +30 -9
  157. alita_sdk/runtime/utils/utils.py +36 -0
  158. alita_sdk/tools/__init__.py +134 -35
  159. alita_sdk/tools/ado/repos/__init__.py +51 -32
  160. alita_sdk/tools/ado/repos/repos_wrapper.py +148 -89
  161. alita_sdk/tools/ado/test_plan/__init__.py +25 -9
  162. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +23 -1
  163. alita_sdk/tools/ado/utils.py +1 -18
  164. alita_sdk/tools/ado/wiki/__init__.py +25 -12
  165. alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
  166. alita_sdk/tools/ado/work_item/__init__.py +26 -13
  167. alita_sdk/tools/ado/work_item/ado_wrapper.py +73 -11
  168. alita_sdk/tools/advanced_jira_mining/__init__.py +11 -8
  169. alita_sdk/tools/aws/delta_lake/__init__.py +13 -9
  170. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  171. alita_sdk/tools/azure_ai/search/__init__.py +11 -8
  172. alita_sdk/tools/azure_ai/search/api_wrapper.py +1 -1
  173. alita_sdk/tools/base/tool.py +5 -1
  174. alita_sdk/tools/base_indexer_toolkit.py +271 -84
  175. alita_sdk/tools/bitbucket/__init__.py +17 -11
  176. alita_sdk/tools/bitbucket/api_wrapper.py +59 -11
  177. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +49 -35
  178. alita_sdk/tools/browser/__init__.py +5 -4
  179. alita_sdk/tools/carrier/__init__.py +5 -6
  180. alita_sdk/tools/carrier/backend_reports_tool.py +6 -6
  181. alita_sdk/tools/carrier/run_ui_test_tool.py +6 -6
  182. alita_sdk/tools/carrier/ui_reports_tool.py +5 -5
  183. alita_sdk/tools/chunkers/__init__.py +3 -1
  184. alita_sdk/tools/chunkers/code/treesitter/treesitter.py +37 -13
  185. alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
  186. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  187. alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
  188. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  189. alita_sdk/tools/cloud/aws/__init__.py +10 -7
  190. alita_sdk/tools/cloud/azure/__init__.py +10 -7
  191. alita_sdk/tools/cloud/gcp/__init__.py +10 -7
  192. alita_sdk/tools/cloud/k8s/__init__.py +10 -7
  193. alita_sdk/tools/code/linter/__init__.py +10 -8
  194. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  195. alita_sdk/tools/code/sonar/__init__.py +11 -8
  196. alita_sdk/tools/code_indexer_toolkit.py +82 -22
  197. alita_sdk/tools/confluence/__init__.py +22 -16
  198. alita_sdk/tools/confluence/api_wrapper.py +107 -30
  199. alita_sdk/tools/confluence/loader.py +14 -2
  200. alita_sdk/tools/custom_open_api/__init__.py +12 -5
  201. alita_sdk/tools/elastic/__init__.py +11 -8
  202. alita_sdk/tools/elitea_base.py +493 -30
  203. alita_sdk/tools/figma/__init__.py +58 -11
  204. alita_sdk/tools/figma/api_wrapper.py +1235 -143
  205. alita_sdk/tools/figma/figma_client.py +73 -0
  206. alita_sdk/tools/figma/toon_tools.py +2748 -0
  207. alita_sdk/tools/github/__init__.py +14 -15
  208. alita_sdk/tools/github/github_client.py +224 -100
  209. alita_sdk/tools/github/graphql_client_wrapper.py +119 -33
  210. alita_sdk/tools/github/schemas.py +14 -5
  211. alita_sdk/tools/github/tool.py +5 -1
  212. alita_sdk/tools/github/tool_prompts.py +9 -22
  213. alita_sdk/tools/gitlab/__init__.py +16 -11
  214. alita_sdk/tools/gitlab/api_wrapper.py +218 -48
  215. alita_sdk/tools/gitlab_org/__init__.py +10 -9
  216. alita_sdk/tools/gitlab_org/api_wrapper.py +63 -64
  217. alita_sdk/tools/google/bigquery/__init__.py +13 -12
  218. alita_sdk/tools/google/bigquery/tool.py +5 -1
  219. alita_sdk/tools/google_places/__init__.py +11 -8
  220. alita_sdk/tools/google_places/api_wrapper.py +1 -1
  221. alita_sdk/tools/jira/__init__.py +17 -10
  222. alita_sdk/tools/jira/api_wrapper.py +92 -41
  223. alita_sdk/tools/keycloak/__init__.py +11 -8
  224. alita_sdk/tools/localgit/__init__.py +9 -3
  225. alita_sdk/tools/localgit/local_git.py +62 -54
  226. alita_sdk/tools/localgit/tool.py +5 -1
  227. alita_sdk/tools/memory/__init__.py +12 -4
  228. alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
  229. alita_sdk/tools/ocr/__init__.py +11 -8
  230. alita_sdk/tools/openapi/__init__.py +491 -106
  231. alita_sdk/tools/openapi/api_wrapper.py +1368 -0
  232. alita_sdk/tools/openapi/tool.py +20 -0
  233. alita_sdk/tools/pandas/__init__.py +20 -12
  234. alita_sdk/tools/pandas/api_wrapper.py +38 -25
  235. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  236. alita_sdk/tools/postman/__init__.py +10 -9
  237. alita_sdk/tools/pptx/__init__.py +11 -10
  238. alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
  239. alita_sdk/tools/qtest/__init__.py +31 -11
  240. alita_sdk/tools/qtest/api_wrapper.py +2135 -86
  241. alita_sdk/tools/rally/__init__.py +10 -9
  242. alita_sdk/tools/rally/api_wrapper.py +1 -1
  243. alita_sdk/tools/report_portal/__init__.py +12 -8
  244. alita_sdk/tools/salesforce/__init__.py +10 -8
  245. alita_sdk/tools/servicenow/__init__.py +17 -15
  246. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  247. alita_sdk/tools/sharepoint/__init__.py +10 -7
  248. alita_sdk/tools/sharepoint/api_wrapper.py +129 -38
  249. alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
  250. alita_sdk/tools/sharepoint/utils.py +8 -2
  251. alita_sdk/tools/slack/__init__.py +10 -7
  252. alita_sdk/tools/slack/api_wrapper.py +2 -2
  253. alita_sdk/tools/sql/__init__.py +12 -9
  254. alita_sdk/tools/testio/__init__.py +10 -7
  255. alita_sdk/tools/testrail/__init__.py +11 -10
  256. alita_sdk/tools/testrail/api_wrapper.py +1 -1
  257. alita_sdk/tools/utils/__init__.py +9 -4
  258. alita_sdk/tools/utils/content_parser.py +103 -18
  259. alita_sdk/tools/utils/text_operations.py +410 -0
  260. alita_sdk/tools/utils/tool_prompts.py +79 -0
  261. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +30 -13
  262. alita_sdk/tools/xray/__init__.py +13 -9
  263. alita_sdk/tools/yagmail/__init__.py +9 -3
  264. alita_sdk/tools/zephyr/__init__.py +10 -7
  265. alita_sdk/tools/zephyr_enterprise/__init__.py +11 -7
  266. alita_sdk/tools/zephyr_essential/__init__.py +10 -7
  267. alita_sdk/tools/zephyr_essential/api_wrapper.py +30 -13
  268. alita_sdk/tools/zephyr_essential/client.py +2 -2
  269. alita_sdk/tools/zephyr_scale/__init__.py +11 -8
  270. alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
  271. alita_sdk/tools/zephyr_squad/__init__.py +10 -7
  272. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +154 -8
  273. alita_sdk-0.3.627.dist-info/RECORD +468 -0
  274. alita_sdk-0.3.627.dist-info/entry_points.txt +2 -0
  275. alita_sdk-0.3.379.dist-info/RECORD +0 -360
  276. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
  277. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
  278. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,20 @@
1
+ from typing import Optional, Type
2
+
3
+ from pydantic import BaseModel, Field, field_validator
4
+
5
+ from ..base.tool import BaseAction
6
+ from .api_wrapper import OpenApiApiWrapper
7
+
8
+
9
+ class OpenApiAction(BaseAction):
10
+ """Tool for executing a single OpenAPI operation."""
11
+
12
+ api_wrapper: OpenApiApiWrapper = Field(default_factory=OpenApiApiWrapper)
13
+ name: str
14
+ description: str = ""
15
+ args_schema: Optional[Type[BaseModel]] = None
16
+
17
+ @field_validator('name', mode='before')
18
+ @classmethod
19
+ def remove_spaces(cls, v: str) -> str:
20
+ return v.replace(' ', '')
@@ -5,7 +5,8 @@ from pydantic import BaseModel, ConfigDict, create_model, Field
5
5
 
6
6
  from .api_wrapper import PandasWrapper
7
7
  from ..base.tool import BaseAction
8
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
8
+ from ..utils import clean_string, get_max_toolkit_length
9
+ from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
9
10
 
10
11
  name = "pandas"
11
12
 
@@ -21,19 +22,22 @@ def get_tools(tool):
21
22
 
22
23
  class PandasToolkit(BaseToolkit):
23
24
  tools: List[BaseTool] = []
24
- toolkit_max_length: int = 0
25
25
 
26
26
  @staticmethod
27
27
  def toolkit_config_schema() -> BaseModel:
28
28
  selected_tools = {x['name']: x['args_schema'].schema() for x in PandasWrapper.model_construct().get_available_tools()}
29
- PandasToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
30
29
  return create_model(
31
30
  name,
32
- bucket_name=(str, Field(default=None, title="Bucket name", description="Bucket where the content file is stored", json_schema_extra={'toolkit_name': True, 'max_toolkit_length': PandasToolkit.toolkit_max_length})),
31
+ bucket_name=(Optional[str], Field(default=None, title="Bucket name", description="Bucket where the content file is stored")),
33
32
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
34
- __config__=ConfigDict(json_schema_extra={'metadata': {"label": "Pandas", "icon_url": "pandas-icon.svg",
35
- "categories": ["analysis"],
36
- "extra_categories": ["data science", "data manipulation", "dataframes"]}})
33
+ __config__=ConfigDict(json_schema_extra={'metadata': {
34
+ "label": "Pandas (Deprecated)",
35
+ "icon_url": "pandas-icon.svg",
36
+ "categories": ["analysis"],
37
+ "deprecated": True,
38
+ "deprecation_message": "This toolkit is deprecated. Use the 'Data Analysis' internal tool instead. Enable it via the 'Internal Tools' menu in chat.",
39
+ "extra_categories": ["data science", "data manipulation", "dataframes"]
40
+ }})
37
41
  )
38
42
 
39
43
  @classmethod
@@ -41,17 +45,21 @@ class PandasToolkit(BaseToolkit):
41
45
  if selected_tools is None:
42
46
  selected_tools = []
43
47
  csv_tool_api_wrapper = PandasWrapper(**kwargs)
44
- prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
45
48
  available_tools = csv_tool_api_wrapper.get_available_tools()
46
49
  tools = []
47
50
  for tool in available_tools:
48
51
  if selected_tools and tool["name"] not in selected_tools:
49
52
  continue
53
+ description = tool["description"]
54
+ if toolkit_name:
55
+ description = f"Toolkit: {toolkit_name}\n{description}"
56
+ description = description[:1000]
50
57
  tools.append(BaseAction(
51
- api_wrapper=csv_tool_api_wrapper,
52
- name=prefix + tool["name"],
53
- description=tool["description"],
54
- args_schema=tool["args_schema"]
58
+ api_wrapper=pandas_api_wrapper,
59
+ name=tool["name"],
60
+ description=description,
61
+ args_schema=tool["args_schema"],
62
+ metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
55
63
  ))
56
64
  return cls(tools=tools)
57
65
 
@@ -158,39 +158,62 @@ class PandasWrapper(BaseToolApiWrapper):
158
158
  f"Retrying Code Generation ({attempts}/{max_retries})..."
159
159
  )
160
160
 
161
- def process_query(self, query: str, filename: str) -> str:
162
- """Analyze and process using query on dataset"""
161
+ def pandas_analyze_data(self, query: str, filename: str) -> str:
162
+ """Analyze data from a file using natural language query.
163
+
164
+ This tool allows you to perform data analysis operations on files using natural language.
165
+ It automatically generates and executes Python pandas code based on your query.
166
+
167
+ Supported file formats: CSV, Excel (.xlsx, .xls), Parquet, JSON, XML, HDF5, Feather, Pickle
168
+
169
+ Parameters:
170
+ query: Natural language description of the analysis to perform. Examples:
171
+ - "Calculate the average sales by region"
172
+ - "Show me a bar chart of products by revenue"
173
+ - "Filter rows where price > 100 and status is 'active'"
174
+ - "What is the correlation between age and income?"
175
+ filename: Name of the file in the artifact bucket (e.g., 'sales_data.csv', 'report.xlsx')
176
+
177
+ Returns:
178
+ Analysis results as text, or confirmation message if a chart was generated and saved.
179
+ Charts are automatically saved to the artifact bucket as PNG files.
180
+
181
+ Examples:
182
+ - pandas_analyze_data(query="Show summary statistics", filename="data.csv")
183
+ - pandas_analyze_data(query="Create a histogram of ages", filename="customers.xlsx")
184
+ - pandas_analyze_data(query="What's the total revenue by month?", filename="sales.parquet")
185
+ """
163
186
  df = self._get_dataframe(filename)
164
187
  code = self.generate_code_with_retries(df, query)
165
- self._log_tool_event(tool_name="process_query",
188
+ self._log_tool_event(tool_name="pandas_analyze_data",
166
189
  message=f"Executing generated code... \n\n```python\n{code}\n```")
167
190
  try:
168
191
  result = self.execute_code(df, code)
169
192
  except Exception as e:
170
193
  logger.error(f"Code execution failed: {format_exc()}")
171
- self._log_tool_event(tool_name="process_query",
172
- message=f"Executing generated code... \n\n```python\n{code}\n```")
173
194
  raise
174
- self._log_tool_event(tool_name="process_query",
175
- message=f"Executing generated code... \n\n```python\n{code}\n```")
176
195
  if result.get("df") is not None:
177
196
  df = result.pop("df")
178
197
  # Not saving dataframe to artifact repo for now
179
198
  # self._save_dataframe(df, filename)
180
199
  if result.get('chart'):
200
+ chart_results = []
181
201
  if isinstance(result['chart'], list):
182
202
  for ind, chart in enumerate(result['chart']):
183
203
  chart_filename = f"chart_{uuid4()}.png"
184
204
  chart_data = base64.b64decode(chart)
185
205
  self.alita.create_artifact(self.bucket_name, chart_filename, chart_data)
186
- result['result'] = f"Chart #{ind} saved to {chart_filename}"
206
+ chart_url = f"{self.alita.base_url}/api/v1/artifacts/artifact/default/{self.alita.project_id}/{self.bucket_name}/{chart_filename}"
207
+ chart_results.append(f"Chart #{ind+1} saved and available at: {chart_url}")
208
+ result['result'] = "\n".join(chart_results)
187
209
  else:
188
210
  # Handle single chart case (not in a list)
189
211
  chart = result['chart']
190
212
  chart_filename = f"chart_{uuid4()}.png"
191
213
  chart_data = base64.b64decode(chart)
192
214
  self.alita.create_artifact(self.bucket_name, chart_filename, chart_data)
193
- result['result'] = f"Chart saved to {chart_filename}"
215
+ chart_url = f"{self.alita.base_url}/api/v1/artifacts/artifact/default/{self.alita.project_id}/{self.bucket_name}/{chart_filename}"
216
+ result['result'] = f"Chart saved and available at: {chart_url}\n\nYou can embed this image in your response using markdown: ![Chart]({chart_url})"
194
217
  return result.get("result", None)
195
218
 
196
219
  def save_dataframe(self, source_df: str, target_file: str) -> str:
@@ -253,23 +276,13 @@ class PandasWrapper(BaseToolApiWrapper):
253
276
  def get_available_tools(self):
254
277
  return [
255
278
  {
256
- "name": "process_query",
257
- "ref": self.process_query,
258
- "description": self.process_query.__doc__,
259
- "args_schema": create_model(
260
- "ProcessQueryModel",
261
- query=(str, Field(description="Task to solve")),
262
- filename=(str, Field(description="File to be processed"))
263
- )
264
- },
265
- {
266
- "name": "save_dataframe",
267
- "ref": self.save_dataframe,
268
- "description": self.save_dataframe.__doc__,
279
+ "name": "pandas_analyze_data",
280
+ "ref": self.pandas_analyze_data,
281
+ "description": self.pandas_analyze_data.__doc__,
269
282
  "args_schema": create_model(
270
- "SaveDataFrameModel",
271
- source_df=(str, Field(description="Source dataframe file to be saved")),
272
- target_file=(str, Field(description="Target filename with extension for saving"))
283
+ "AnalyseDataModel",
284
+ query=(str, Field(description="Natural language query describing what analysis to perform on the data")),
285
+ filename=(str, Field(description="Name of the file to analyze (e.g., 'data.csv', 'report.xlsx')"))
273
286
  )
274
287
  }
275
288
  ]
@@ -39,7 +39,9 @@ class CodeGenerator:
39
39
  {"role": "user", "content": [{"type": "text", "text": prompt}]}
40
40
  ]
41
41
  # Generate the code
42
- code = self.llm.invoke(messages).content
42
+ from alita_sdk.runtime.langchain.utils import extract_text_from_completion
43
+ completion = self.llm.invoke(messages)
44
+ code = extract_text_from_completion(completion)
43
45
  return self.validate_and_clean_code(code)
44
46
 
45
47
  except Exception as e:
@@ -6,8 +6,9 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, field_validator
6
6
  from ..base.tool import BaseAction
7
7
 
8
8
  from .api_wrapper import PostmanApiWrapper
9
- from ..utils import clean_string, get_max_toolkit_length, TOOLKIT_SPLITTER, check_connection_response
9
+ from ..utils import clean_string, get_max_toolkit_length, check_connection_response
10
10
  from ...configurations.postman import PostmanConfiguration
11
+ from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
11
12
 
12
13
  name = "postman"
13
14
 
@@ -43,14 +44,11 @@ def get_tools(tool):
43
44
 
44
45
  class PostmanToolkit(BaseToolkit):
45
46
  tools: List[BaseTool] = []
46
- toolkit_max_length: int = 0
47
47
 
48
48
  @staticmethod
49
49
  def toolkit_config_schema() -> BaseModel:
50
50
  selected_tools = {x['name']: x['args_schema'].schema(
51
51
  ) for x in PostmanApiWrapper.model_construct().get_available_tools()}
52
- PostmanToolkit.toolkit_max_length = get_max_toolkit_length(
53
- selected_tools)
54
52
  m = create_model(
55
53
  name,
56
54
  postman_configuration=(Optional[PostmanConfiguration], Field(description="Postman Configuration",
@@ -89,20 +87,23 @@ class PostmanToolkit(BaseToolkit):
89
87
  **kwargs['postman_configuration'],
90
88
  }
91
89
  postman_api_wrapper = PostmanApiWrapper(**wrapper_payload)
92
- prefix = clean_string(str(toolkit_name), cls.toolkit_max_length) + \
93
- TOOLKIT_SPLITTER if toolkit_name else ''
94
90
  available_tools = postman_api_wrapper.get_available_tools()
95
91
  tools = []
96
92
  for tool in available_tools:
97
93
  if selected_tools:
98
94
  if tool["name"] not in selected_tools:
99
95
  continue
96
+ description = f"{tool['description']}\nAPI URL: {postman_api_wrapper.base_url}"
97
+ if toolkit_name:
98
+ description = f"{description}\nToolkit: {toolkit_name}"
99
+ description = description[:1000]
100
100
  tools.append(PostmanAction(
101
101
  api_wrapper=postman_api_wrapper,
102
- name=prefix + tool["name"],
102
+ name=tool["name"],
103
103
  mode=tool["mode"],
104
- description=f"{tool['description']}\nAPI URL: {postman_api_wrapper.base_url}",
105
- args_schema=tool["args_schema"]
104
+ description=description,
105
+ args_schema=tool["args_schema"],
106
+ metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
106
107
  ))
107
108
  return cls(tools=tools)
108
109
 
@@ -7,7 +7,8 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
7
7
  from .pptx_wrapper import PPTXWrapper
8
8
 
9
9
  from ..base.tool import BaseAction
10
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
10
+ from ..utils import clean_string, get_max_toolkit_length
11
+ from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
11
12
 
12
13
  logger = logging.getLogger(__name__)
13
14
 
@@ -27,8 +28,6 @@ def get_tools(tool):
27
28
  ).get_tools()
28
29
 
29
30
 
30
- TOOLKIT_MAX_LENGTH = 25
31
-
32
31
  class PPTXToolkit(BaseToolkit):
33
32
  """
34
33
  PowerPoint (PPTX) manipulation toolkit for Alita.
@@ -45,8 +44,7 @@ class PPTXToolkit(BaseToolkit):
45
44
 
46
45
  return create_model(
47
46
  name,
48
- bucket_name=(str, Field(description="Bucket name where PPTX files are stored",
49
- json_schema_extra={'toolkit_name': True, 'max_toolkit_length': TOOLKIT_MAX_LENGTH})),
47
+ bucket_name=(str, Field(description="Bucket name where PPTX files are stored")),
50
48
  selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
51
49
  __config__=ConfigDict(json_schema_extra={
52
50
  'metadata': {
@@ -75,19 +73,22 @@ class PPTXToolkit(BaseToolkit):
75
73
  selected_tools = []
76
74
 
77
75
  pptx_api_wrapper = PPTXWrapper(**kwargs)
78
- prefix = clean_string(toolkit_name, TOOLKIT_MAX_LENGTH) + TOOLKIT_SPLITTER if toolkit_name else ''
79
76
  available_tools = pptx_api_wrapper.get_available_tools()
80
77
  tools = []
81
78
 
82
79
  for tool in available_tools:
83
80
  if selected_tools and tool["name"] not in selected_tools:
84
81
  continue
85
-
82
+ description = tool["description"]
83
+ if toolkit_name:
84
+ description = f"Toolkit: {toolkit_name}\n{description}"
85
+ description = description[:1000]
86
86
  tools.append(BaseAction(
87
87
  api_wrapper=pptx_api_wrapper,
88
- name=prefix + tool["name"],
89
- description=tool["description"],
90
- args_schema=tool["args_schema"]
88
+ name=tool["name"],
89
+ description=description,
90
+ args_schema=tool["args_schema"],
91
+ metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
91
92
  ))
92
93
 
93
94
  return cls(tools=tools)
@@ -547,7 +547,7 @@ class PPTXWrapper(BaseToolApiWrapper):
547
547
  file_name=(str, Field(description="PPTX file name in the bucket")),
548
548
  output_file_name=(str, Field(description="Output PPTX file name to save in the bucket")),
549
549
  content_description=(str, Field(description="Detailed description of what content to put where in the template")),
550
- pdf_file_name=(str, Field(description="Optional PDF file name in the bucket that matches the PPTX template 1:1", default=None))
550
+ pdf_file_name=(Optional[str], Field(description="Optional PDF file name in the bucket that matches the PPTX template 1:1", default=None))
551
551
  )
552
552
  },{
553
553
  "name": "translate_presentation",
@@ -7,8 +7,10 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, SecretStr
7
7
  from .api_wrapper import QtestApiWrapper
8
8
  from .tool import QtestAction
9
9
  from ..elitea_base import filter_missconfigured_index_tools
10
- from ..utils import clean_string, get_max_toolkit_length, TOOLKIT_SPLITTER, check_connection_response
10
+ from ..utils import clean_string, get_max_toolkit_length, check_connection_response
11
11
  from ...configurations.qtest import QtestConfiguration
12
+ from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
13
+ from ...configurations.pgvector import PgVectorConfiguration
12
14
 
13
15
  name = "qtest"
14
16
 
@@ -20,27 +22,40 @@ def get_tools(tool):
20
22
  no_of_tests_shown_in_dql_search=tool['settings'].get('no_of_tests_shown_in_dql_search'),
21
23
  qtest_configuration=tool['settings']['qtest_configuration'],
22
24
  toolkit_name=tool.get('toolkit_name'),
23
- llm=tool['settings'].get('llm', None)
25
+ llm=tool['settings'].get('llm', None),
26
+ alita=tool['settings'].get('alita', None),
27
+
28
+ # indexer settings
29
+ pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
30
+ collection_name=str(tool.get('toolkit_name', '')),
31
+ embedding_model=tool['settings'].get('embedding_model', None),
32
+ vectorstore_type="PGVector"
24
33
  )
25
34
  return toolkit.tools
26
35
 
27
36
 
28
37
  class QtestToolkit(BaseToolkit):
29
38
  tools: List[BaseTool] = []
30
- toolkit_max_length: int = 0
31
39
 
32
40
  @staticmethod
33
41
  def toolkit_config_schema() -> BaseModel:
34
42
  selected_tools = {x['name']: x['args_schema'].schema() for x in QtestApiWrapper.model_construct().get_available_tools()}
35
- QtestToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
36
43
  m = create_model(
37
44
  name,
38
45
  qtest_configuration=(QtestConfiguration, Field(description="QTest API token", json_schema_extra={
39
46
  'configuration_types': ['qtest']})),
40
- qtest_project_id=(int, Field(default=None, description="QTest project id", json_schema_extra={'toolkit_name': True,
41
- 'max_toolkit_length': QtestToolkit.toolkit_max_length})),
47
+ qtest_project_id=(int, Field(description="QTest project id")),
42
48
  no_of_tests_shown_in_dql_search=(Optional[int], Field(description="Max number of items returned by dql search",
43
49
  default=10)),
50
+ # indexer configuration
51
+ pgvector_configuration=(Optional[PgVectorConfiguration], Field(
52
+ default=None,
53
+ description="PgVector Configuration for indexing",
54
+ json_schema_extra={'configuration_types': ['pgvector']})),
55
+ embedding_model=(Optional[str], Field(
56
+ default=None,
57
+ description="Embedding model configuration for indexing",
58
+ json_schema_extra={'configuration_model': 'embedding'})),
44
59
 
45
60
  selected_tools=(List[Literal[tuple(selected_tools)]],
46
61
  Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
@@ -74,23 +89,28 @@ class QtestToolkit(BaseToolkit):
74
89
  **kwargs,
75
90
  # TODO use qtest_configuration fields
76
91
  **kwargs['qtest_configuration'],
92
+ **(kwargs.get('pgvector_configuration') or {}),
77
93
  }
78
94
  qtest_api_wrapper = QtestApiWrapper(**wrapper_payload)
79
- prefix = clean_string(str(toolkit_name), cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
80
95
  available_tools = qtest_api_wrapper.get_available_tools()
81
96
  tools = []
82
97
  for tool in available_tools:
83
98
  if selected_tools:
84
99
  if tool["name"] not in selected_tools:
85
100
  continue
101
+ description = f"{tool['description']}\nUrl: {qtest_api_wrapper.base_url}. Project id: {qtest_api_wrapper.qtest_project_id}"
102
+ if toolkit_name:
103
+ description = f"{description}\nToolkit: {toolkit_name}"
104
+ description = description[:1000]
86
105
  tools.append(QtestAction(
87
106
  api_wrapper=qtest_api_wrapper,
88
- name=prefix + tool["name"],
107
+ name=tool["name"],
89
108
  mode=tool["mode"],
90
- description=f"{tool['description']}\nUrl: {qtest_api_wrapper.base_url}. Project id: {qtest_api_wrapper.qtest_project_id}",
91
- args_schema=tool["args_schema"]
109
+ description=description,
110
+ args_schema=tool["args_schema"],
111
+ metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
92
112
  ))
93
113
  return cls(tools=tools)
94
114
 
95
115
  def get_tools(self):
96
- return self.tools
116
+ return self.tools