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
@@ -1326,6 +1326,74 @@ class GraphQLClientWrapper(BaseModel):
1326
1326
  except Exception as e:
1327
1327
  raise ValueError(f"'{repo}' repo format is invalid. It should be like 'org-name/repo-name'. Error: {str(e)}")
1328
1328
 
1329
+ def _format_project_error(self, error_message: str) -> str:
1330
+ """
1331
+ Format project access errors with user-friendly guidance.
1332
+
1333
+ Detects permission-related errors and provides actionable guidance for users
1334
+ to fix token permission issues.
1335
+
1336
+ Args:
1337
+ error_message: The original error message from get_project() or get_issue_repo()
1338
+
1339
+ Returns:
1340
+ str: A user-friendly error message with guidance on how to fix the issue
1341
+ """
1342
+ # Detect permission-related errors
1343
+ permission_indicators = [
1344
+ "Resource not accessible",
1345
+ "INSUFFICIENT_SCOPES",
1346
+ "not accessible by personal access token",
1347
+ "requires authentication",
1348
+ "Bad credentials",
1349
+ "401",
1350
+ "403"
1351
+ ]
1352
+
1353
+ is_permission_error = any(
1354
+ indicator.lower() in error_message.lower()
1355
+ for indicator in permission_indicators
1356
+ )
1357
+
1358
+ if is_permission_error:
1359
+ return (
1360
+ "GitHub Token Permission Error\n\n"
1361
+ "Your GitHub token does not have the required 'project' permission "
1362
+ "to access GitHub Projects (ProjectsV2).\n\n"
1363
+ "To fix this:\n"
1364
+ "1. Go to GitHub Settings > Developer settings > Personal access tokens\n"
1365
+ "2. Edit your token and enable the 'project' scope (read/write access to projects)\n"
1366
+ "3. Update your toolkit configuration with the new token\n\n"
1367
+ f"Technical details: {error_message}"
1368
+ )
1369
+
1370
+ # For other errors (not found, network issues, etc.), return with clearer context
1371
+ if "not found" in error_message.lower():
1372
+ return f"Project not found. Please verify the project title exists and is accessible. {error_message}"
1373
+
1374
+ if "No repository data found" in error_message:
1375
+ return (
1376
+ "Repository not found or not accessible. Please verify:\n"
1377
+ "1. The repository name is correct (format: owner/repo-name)\n"
1378
+ "2. Your token has access to this repository\n\n"
1379
+ f"Technical details: {error_message}"
1380
+ )
1381
+
1382
+ return f"Failed to access GitHub project. {error_message}"
1383
+
1384
+ def _format_repo_error(self, error_message: str) -> str:
1385
+ """
1386
+ Format repository access errors with user-friendly guidance.
1387
+
1388
+ Args:
1389
+ error_message: The original error message from get_issue_repo()
1390
+
1391
+ Returns:
1392
+ str: A user-friendly error message with guidance
1393
+ """
1394
+ # Reuse the project error formatting logic as the errors are similar
1395
+ return self._format_project_error(error_message)
1396
+
1329
1397
  def _get_repo_extra_info(self, repository: Dict[str, Any]) -> Tuple[str, List[Dict[str, Any]], List[Dict[str, Any]]]:
1330
1398
  """Helper to extract repository ID, labels and assignable users of the repository."""
1331
1399
  repository_id = repository.get("repositoryId")
@@ -1356,22 +1424,31 @@ class GraphQLClientWrapper(BaseModel):
1356
1424
  except ValueError as e:
1357
1425
  return str(e)
1358
1426
 
1359
- try:
1360
- result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
1361
- project = result.get("project")
1362
- project_id = result.get("projectId")
1363
- if issue_repo:
1364
- try:
1365
- issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
1366
- except ValueError as e:
1367
- return str(e)
1368
-
1369
- issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
1370
- repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
1371
- else:
1372
- repository_id, labels, assignable_users = self._get_repo_extra_info(result)
1373
- except Exception as e:
1374
- return f"Project has not been found. Error: {str(e)}"
1427
+ # Get project data with type safety check
1428
+ result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
1429
+
1430
+ # Type check: get_project() returns str on error, dict on success
1431
+ if isinstance(result, str):
1432
+ return self._format_project_error(result)
1433
+
1434
+ project = result.get("project")
1435
+ project_id = result.get("projectId")
1436
+
1437
+ if issue_repo:
1438
+ try:
1439
+ issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
1440
+ except ValueError as e:
1441
+ return str(e)
1442
+
1443
+ issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
1444
+
1445
+ # Type check: get_issue_repo() returns str on error, dict on success
1446
+ if isinstance(issue_repo_result, str):
1447
+ return self._format_repo_error(issue_repo_result)
1448
+
1449
+ repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
1450
+ else:
1451
+ repository_id, labels, assignable_users = self._get_repo_extra_info(result)
1375
1452
 
1376
1453
  missing_fields = []
1377
1454
  updated_fields = []
@@ -1444,26 +1521,35 @@ class GraphQLClientWrapper(BaseModel):
1444
1521
  except Exception as e:
1445
1522
  return str(e)
1446
1523
 
1447
- try:
1448
- result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
1449
- project = result.get("project")
1450
- project_id = result.get("projectId")
1451
-
1452
- if issue_repo:
1453
- try:
1454
- issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
1455
- except ValueError as e:
1456
- return str(e)
1457
-
1458
- issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
1459
- repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
1460
- else:
1461
- repository_id, labels, assignable_users = self._get_repo_extra_info(result)
1462
- except Exception as e:
1463
- return f"Project has not been found. Error: {str(e)}"
1524
+ # Get project data with type safety check
1525
+ result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
1526
+
1527
+ # Type check: get_project() returns str on error, dict on success
1528
+ if isinstance(result, str):
1529
+ return self._format_project_error(result)
1530
+
1531
+ project = result.get("project")
1532
+ project_id = result.get("projectId")
1533
+
1534
+ if issue_repo:
1535
+ try:
1536
+ issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
1537
+ except ValueError as e:
1538
+ return str(e)
1539
+
1540
+ issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
1541
+
1542
+ # Type check: get_issue_repo() returns str on error, dict on success
1543
+ if isinstance(issue_repo_result, str):
1544
+ return self._format_repo_error(issue_repo_result)
1545
+
1546
+ repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
1547
+ else:
1548
+ repository_id, labels, assignable_users = self._get_repo_extra_info(result)
1464
1549
 
1465
1550
  missing_fields = []
1466
1551
  fields_to_update = []
1552
+ updated_fields = []
1467
1553
 
1468
1554
  if fields:
1469
1555
  try:
@@ -1,6 +1,9 @@
1
1
  from typing import Dict, List, Optional, Any
2
2
  from pydantic import BaseModel, Field, SecretStr, create_model
3
3
 
4
+ from alita_sdk.tools.utils.tool_prompts import UPDATE_FILE_PROMPT_WITH_PATH
5
+
6
+
4
7
  # Base schemas for GitHub API wrapper
5
8
  class GitHubAuthConfig(BaseModel):
6
9
  github_access_token: Optional[SecretStr] = None
@@ -28,6 +31,12 @@ CreateBranchName = create_model(
28
31
  proposed_branch_name=(str, Field(description="The name of the new branch to create, e.g. `feature-branch`"))
29
32
  )
30
33
 
34
+ DeleteBranchName = create_model(
35
+ "DeleteBranchName",
36
+ branch_name=(str, Field(description="The name of the branch to delete, e.g. `feature-branch`")),
37
+ force=(Optional[bool], Field(default=False, description="Force deletion even if branch is the current active branch"))
38
+ )
39
+
31
40
  DirectoryPath = create_model(
32
41
  "DirectoryPath",
33
42
  directory_path=(str, Field(description="The path of the directory, e.g. `src/my_dir`"))
@@ -42,7 +51,7 @@ ReadFile = create_model(
42
51
 
43
52
  UpdateFile = create_model(
44
53
  "UpdateFile",
45
- file_query=(str, Field(description="File path and content to update with OLD and NEW markers")),
54
+ file_query=(str, Field(description=UPDATE_FILE_PROMPT_WITH_PATH)),
46
55
  repo_name=(Optional[str], Field(default=None, description="Name of the repository (e.g., 'owner/repo'). If None, uses the default repository.")),
47
56
  commit_message=(Optional[str], Field(default=None, description="Commit message for the update operation")),
48
57
  )
@@ -92,7 +101,7 @@ SearchIssues = create_model(
92
101
  "SearchIssues",
93
102
  search_query=(str, Field(description="Keywords or query for searching issues and PRs in Github")),
94
103
  repo_name=(Optional[str], Field(description="Name of the repository to search issues in", default=None)),
95
- max_count=(Optional[int], Field(description="Maximum number of issues to return", default=30))
104
+ max_count=(Optional[int], Field(description="Maximum number of issues to return", default=30, gt=0))
96
105
  )
97
106
 
98
107
  CreateIssue = create_model(
@@ -152,7 +161,7 @@ GetCommits = create_model(
152
161
  since=(Optional[str], Field(description="Only commits after this date will be returned (ISO format)", default=None)),
153
162
  until=(Optional[str], Field(description="Only commits before this date will be returned (ISO format)", default=None)),
154
163
  author=(Optional[str], Field(description="The author of the commits", default=None)),
155
- max_count=(Optional[int], Field(description="Maximum number of commits to return (default: 30)", default=30))
164
+ max_count=(Optional[int], Field(description="Maximum number of commits to return (default: 30)", default=30, gt=0))
156
165
  )
157
166
 
158
167
  GetCommitChanges = create_model(
@@ -213,7 +222,7 @@ ListProjectIssues = create_model(
213
222
  "ListProjectIssues",
214
223
  board_repo=(str, Field(description="The organization and repository for the board (project). Example: 'org-name/repo-name'")),
215
224
  project_number=(int, Field(description="The project number as shown in the project URL")),
216
- items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100))
225
+ items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100, gt=0))
217
226
  )
218
227
 
219
228
  SearchProjectIssues = create_model(
@@ -221,7 +230,7 @@ SearchProjectIssues = create_model(
221
230
  board_repo=(str, Field(description="The organization and repository for the board (project). Example: 'org-name/repo-name'")),
222
231
  project_number=(int, Field(description="The project number as shown in the project URL")),
223
232
  search_query=(str, Field(description="Search query for filtering issues. Examples: 'status:In Progress', 'release:v1.0'")),
224
- items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100))
233
+ items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100, gt=0))
225
234
  )
226
235
 
227
236
  ListProjectViews = create_model(
@@ -29,6 +29,10 @@ class GitHubAction(BaseTool):
29
29
  ) -> str:
30
30
  """Use the GitHub API to run an operation."""
31
31
  try:
32
- return self.api_wrapper.run(self.mode, *args, **kwargs)
32
+ # Strip numeric suffix added for deduplication (_2, _3, etc.)
33
+ # to get the original tool name that exists in the wrapper
34
+ import re
35
+ mode = re.sub(r'_\d+$', '', self.mode) if self.mode else self.mode
36
+ return self.api_wrapper.run(mode, *args, **kwargs)
33
37
  except Exception as e:
34
38
  return f"Error: {format_exc()}"
@@ -1,31 +1,18 @@
1
1
  CREATE_FILE_PROMPT = """Create new file in your github repository."""
2
2
 
3
- UPDATE_FILE_PROMPT = """Updates the contents of a file in repository. Input MUST strictly follow these rules:
4
- Specify the file to modify by passing a full file path (the path must not start with a slash); Specify at lest 2 lines of the old contents which you would like to replace wrapped in OLD <<<< and >>>> OLD; Specify the new contents which you would like to replace the old contents with wrapped in NEW <<<< and >>>> NEW; NEW content may contain lines from OLD content in case you want to add content without removing the old content
5
3
 
6
- Example 1: Replace "old contents" to "new contents" in the file /test/test.txt from , pass in the following string:
4
+ DELETE_BRANCH_PROMPT = """Delete a branch from the GitHub repository.
7
5
 
8
- test/test.txt
6
+ IMPORTANT: This tool will NOT delete protected branches:
7
+ - 'main' and 'master' branches are always protected
8
+ - The configured base branch is protected
9
+ - The currently active branch is protected (unless force=True)
9
10
 
10
- This is text that will not be changed
11
- OLD <<<<
12
- old contents
13
- >>>> OLD
14
- NEW <<<<
15
- new contents
16
- >>>> NEW
11
+ Parameters:
12
+ - branch_name: The name of the branch to delete (e.g., 'feature-branch')
13
+ - force: Set to True to delete even if it's the current active branch (default: False)
17
14
 
18
- Example 2: Extend "existing contents" with new contents" in the file /test/test.txt, pass in the following string:
19
-
20
- test/test.txt
21
-
22
- OLD <<<<
23
- existing contents
24
- >>>> OLD
25
- NEW <<<<
26
- existing contents
27
- new contents
28
- >>>> NEW"""
15
+ Returns a success or error message."""
29
16
 
30
17
  CREATE_ISSUE_PROMPT = """
31
18
  Tool allows to create a new issue in a GitHub repository.
@@ -8,14 +8,15 @@ from pydantic.fields import Field
8
8
 
9
9
  from .api_wrapper import GitLabAPIWrapper
10
10
  from ..elitea_base import filter_missconfigured_index_tools
11
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
11
+ from ..utils import clean_string, get_max_toolkit_length
12
12
  from ...configurations.gitlab import GitlabConfiguration
13
13
  from ...configurations.pgvector import PgVectorConfiguration
14
+ from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
14
15
 
15
16
  name = "gitlab"
16
17
 
17
18
 
18
- def get_tools(tool):
19
+ def get_toolkit(tool):
19
20
  return AlitaGitlabToolkit().get_toolkit(
20
21
  selected_tools=tool['settings'].get('selected_tools', []),
21
22
  repository=tool['settings']['repository'],
@@ -30,20 +31,21 @@ def get_tools(tool):
30
31
  embedding_model=tool['settings'].get('embedding_model'),
31
32
  vectorstore_type="PGVector",
32
33
  toolkit_name=tool.get('toolkit_name')
33
- ).get_tools()
34
+ )
35
+
36
+ def get_tools(tool):
37
+ return get_toolkit(tool).get_tools()
34
38
 
35
39
  class AlitaGitlabToolkit(BaseToolkit):
36
40
  tools: List[BaseTool] = []
37
- toolkit_max_length: int = 0
38
41
 
39
42
  @staticmethod
40
43
  def toolkit_config_schema() -> BaseModel:
41
44
  selected_tools = {x['name']: x['args_schema'].schema() for x in
42
45
  GitLabAPIWrapper.model_construct().get_available_tools()}
43
- AlitaGitlabToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
44
46
  return create_model(
45
47
  name,
46
- repository=(str, Field(description="GitLab repository", json_schema_extra={'toolkit_name': True, 'max_toolkit_length': AlitaGitlabToolkit.toolkit_max_length})),
48
+ repository=(str, Field(description="GitLab repository")),
47
49
  gitlab_configuration=(GitlabConfiguration, Field(description="GitLab configuration", json_schema_extra={'configuration_types': ['gitlab']})),
48
50
  branch=(str, Field(description="Main branch", default="main")),
49
51
  # indexer settings
@@ -76,19 +78,22 @@ class AlitaGitlabToolkit(BaseToolkit):
76
78
  **(kwargs.get('embedding_configuration') or {}),
77
79
  }
78
80
  gitlab_api_wrapper = GitLabAPIWrapper(**wrapper_payload)
79
- prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
80
81
  available_tools: List[Dict] = gitlab_api_wrapper.get_available_tools()
81
82
  tools = []
82
83
  for tool in available_tools:
83
84
  if selected_tools:
84
85
  if tool["name"] not in selected_tools:
85
86
  continue
86
-
87
+ description = tool["description"] + f"\nrepo: {gitlab_api_wrapper.repository}"
88
+ if toolkit_name:
89
+ description = f"{description}\nToolkit: {toolkit_name}"
90
+ description = description[:1000]
87
91
  tools.append(BaseAction(
88
92
  api_wrapper=gitlab_api_wrapper,
89
- name=prefix + tool["name"],
90
- description=tool["description"] + f"\nrepo: {gitlab_api_wrapper.repository}",
91
- args_schema=tool["args_schema"]
93
+ name=tool["name"],
94
+ description=description,
95
+ args_schema=tool["args_schema"],
96
+ 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
97
  ))
93
98
  return cls(tools=tools)
94
99