alita-sdk 0.3.257__py3-none-any.whl → 0.3.562__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 +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 +3601 -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 +111 -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 +407 -92
  110. alita_sdk/runtime/langchain/utils.py +102 -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 +24 -9
  124. alita_sdk/runtime/toolkits/datasource.py +13 -6
  125. alita_sdk/runtime/toolkits/mcp.py +780 -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 +1013 -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/mcp_client.py +492 -0
  155. alita_sdk/runtime/utils/mcp_oauth.py +361 -0
  156. alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
  157. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  158. alita_sdk/runtime/utils/streamlit.py +41 -14
  159. alita_sdk/runtime/utils/toolkit_utils.py +28 -9
  160. alita_sdk/runtime/utils/utils.py +48 -0
  161. alita_sdk/tools/__init__.py +135 -37
  162. alita_sdk/tools/ado/__init__.py +2 -2
  163. alita_sdk/tools/ado/repos/__init__.py +15 -19
  164. alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
  165. alita_sdk/tools/ado/test_plan/__init__.py +26 -8
  166. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
  167. alita_sdk/tools/ado/wiki/__init__.py +27 -12
  168. alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
  169. alita_sdk/tools/ado/work_item/__init__.py +27 -12
  170. alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
  171. alita_sdk/tools/advanced_jira_mining/__init__.py +12 -8
  172. alita_sdk/tools/aws/delta_lake/__init__.py +14 -11
  173. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  174. alita_sdk/tools/azure_ai/search/__init__.py +13 -8
  175. alita_sdk/tools/base/tool.py +5 -1
  176. alita_sdk/tools/base_indexer_toolkit.py +454 -110
  177. alita_sdk/tools/bitbucket/__init__.py +27 -19
  178. alita_sdk/tools/bitbucket/api_wrapper.py +285 -27
  179. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
  180. alita_sdk/tools/browser/__init__.py +41 -16
  181. alita_sdk/tools/browser/crawler.py +3 -1
  182. alita_sdk/tools/browser/utils.py +15 -6
  183. alita_sdk/tools/carrier/__init__.py +18 -17
  184. alita_sdk/tools/carrier/backend_reports_tool.py +8 -4
  185. alita_sdk/tools/carrier/excel_reporter.py +8 -4
  186. alita_sdk/tools/chunkers/__init__.py +3 -1
  187. alita_sdk/tools/chunkers/code/codeparser.py +1 -1
  188. alita_sdk/tools/chunkers/sematic/json_chunker.py +2 -1
  189. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  190. alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
  191. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  192. alita_sdk/tools/cloud/aws/__init__.py +11 -7
  193. alita_sdk/tools/cloud/azure/__init__.py +11 -7
  194. alita_sdk/tools/cloud/gcp/__init__.py +11 -7
  195. alita_sdk/tools/cloud/k8s/__init__.py +11 -7
  196. alita_sdk/tools/code/linter/__init__.py +9 -8
  197. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  198. alita_sdk/tools/code/sonar/__init__.py +20 -13
  199. alita_sdk/tools/code_indexer_toolkit.py +199 -0
  200. alita_sdk/tools/confluence/__init__.py +21 -14
  201. alita_sdk/tools/confluence/api_wrapper.py +197 -58
  202. alita_sdk/tools/confluence/loader.py +14 -2
  203. alita_sdk/tools/custom_open_api/__init__.py +11 -5
  204. alita_sdk/tools/elastic/__init__.py +10 -8
  205. alita_sdk/tools/elitea_base.py +546 -64
  206. alita_sdk/tools/figma/__init__.py +11 -8
  207. alita_sdk/tools/figma/api_wrapper.py +352 -153
  208. alita_sdk/tools/github/__init__.py +17 -17
  209. alita_sdk/tools/github/api_wrapper.py +9 -26
  210. alita_sdk/tools/github/github_client.py +81 -12
  211. alita_sdk/tools/github/schemas.py +2 -1
  212. alita_sdk/tools/github/tool.py +5 -1
  213. alita_sdk/tools/gitlab/__init__.py +18 -13
  214. alita_sdk/tools/gitlab/api_wrapper.py +224 -80
  215. alita_sdk/tools/gitlab_org/__init__.py +13 -10
  216. alita_sdk/tools/google/bigquery/__init__.py +13 -13
  217. alita_sdk/tools/google/bigquery/tool.py +5 -1
  218. alita_sdk/tools/google_places/__init__.py +20 -11
  219. alita_sdk/tools/jira/__init__.py +21 -11
  220. alita_sdk/tools/jira/api_wrapper.py +315 -168
  221. alita_sdk/tools/keycloak/__init__.py +10 -8
  222. alita_sdk/tools/localgit/__init__.py +8 -3
  223. alita_sdk/tools/localgit/local_git.py +62 -54
  224. alita_sdk/tools/localgit/tool.py +5 -1
  225. alita_sdk/tools/memory/__init__.py +38 -14
  226. alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
  227. alita_sdk/tools/ocr/__init__.py +10 -8
  228. alita_sdk/tools/openapi/__init__.py +281 -108
  229. alita_sdk/tools/openapi/api_wrapper.py +883 -0
  230. alita_sdk/tools/openapi/tool.py +20 -0
  231. alita_sdk/tools/pandas/__init__.py +18 -11
  232. alita_sdk/tools/pandas/api_wrapper.py +40 -45
  233. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  234. alita_sdk/tools/postman/__init__.py +10 -11
  235. alita_sdk/tools/postman/api_wrapper.py +19 -8
  236. alita_sdk/tools/postman/postman_analysis.py +8 -1
  237. alita_sdk/tools/pptx/__init__.py +10 -10
  238. alita_sdk/tools/qtest/__init__.py +21 -14
  239. alita_sdk/tools/qtest/api_wrapper.py +1784 -88
  240. alita_sdk/tools/rally/__init__.py +12 -10
  241. alita_sdk/tools/report_portal/__init__.py +22 -16
  242. alita_sdk/tools/salesforce/__init__.py +21 -16
  243. alita_sdk/tools/servicenow/__init__.py +20 -16
  244. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  245. alita_sdk/tools/sharepoint/__init__.py +16 -14
  246. alita_sdk/tools/sharepoint/api_wrapper.py +179 -39
  247. alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
  248. alita_sdk/tools/sharepoint/utils.py +8 -2
  249. alita_sdk/tools/slack/__init__.py +11 -7
  250. alita_sdk/tools/sql/__init__.py +21 -19
  251. alita_sdk/tools/sql/api_wrapper.py +71 -23
  252. alita_sdk/tools/testio/__init__.py +20 -13
  253. alita_sdk/tools/testrail/__init__.py +12 -11
  254. alita_sdk/tools/testrail/api_wrapper.py +214 -46
  255. alita_sdk/tools/utils/__init__.py +28 -4
  256. alita_sdk/tools/utils/content_parser.py +182 -62
  257. alita_sdk/tools/utils/text_operations.py +254 -0
  258. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
  259. alita_sdk/tools/xray/__init__.py +17 -14
  260. alita_sdk/tools/xray/api_wrapper.py +58 -113
  261. alita_sdk/tools/yagmail/__init__.py +8 -3
  262. alita_sdk/tools/zephyr/__init__.py +11 -7
  263. alita_sdk/tools/zephyr_enterprise/__init__.py +15 -9
  264. alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
  265. alita_sdk/tools/zephyr_essential/__init__.py +15 -10
  266. alita_sdk/tools/zephyr_essential/api_wrapper.py +297 -54
  267. alita_sdk/tools/zephyr_essential/client.py +6 -4
  268. alita_sdk/tools/zephyr_scale/__init__.py +12 -8
  269. alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
  270. alita_sdk/tools/zephyr_squad/__init__.py +11 -7
  271. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/METADATA +184 -37
  272. alita_sdk-0.3.562.dist-info/RECORD +450 -0
  273. alita_sdk-0.3.562.dist-info/entry_points.txt +2 -0
  274. alita_sdk/tools/bitbucket/tools.py +0 -304
  275. alita_sdk-0.3.257.dist-info/RECORD +0 -343
  276. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/WHEEL +0 -0
  277. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/licenses/LICENSE +0 -0
  278. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/top_level.txt +0 -0
@@ -5,14 +5,15 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
5
5
 
6
6
  from .api_wrapper import AlitaGitHubAPIWrapper
7
7
  from .tool import GitHubAction
8
+ from ..elitea_base import filter_missconfigured_index_tools
8
9
 
9
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
10
+ from ..utils import clean_string, get_max_toolkit_length
10
11
  from ...configurations.github import GithubConfiguration
11
12
  from ...configurations.pgvector import PgVectorConfiguration
12
13
 
13
14
  name = "github"
14
15
 
15
- def _get_toolkit(tool) -> BaseToolkit:
16
+ def get_toolkit(tool) -> BaseToolkit:
16
17
  return AlitaGitHubToolkit().get_toolkit(
17
18
  selected_tools=tool['settings'].get('selected_tools', []),
18
19
  github_base_url=tool['settings'].get('base_url', ''),
@@ -30,21 +31,16 @@ def _get_toolkit(tool) -> BaseToolkit:
30
31
  toolkit_name=tool.get('toolkit_name')
31
32
  )
32
33
 
33
- def get_toolkit():
34
- return AlitaGitHubToolkit.toolkit_config_schema()
35
-
36
34
  def get_tools(tool):
37
- return _get_toolkit(tool).get_tools()
35
+ return get_toolkit(tool).get_tools()
38
36
 
39
37
  class AlitaGitHubToolkit(BaseToolkit):
40
38
  tools: List[BaseTool] = []
41
- toolkit_max_length: int = 0
42
39
 
43
40
  @staticmethod
44
41
  def toolkit_config_schema() -> BaseModel:
45
42
  selected_tools = {x['name']: x['args_schema'].schema() for x in
46
43
  AlitaGitHubAPIWrapper.model_construct().get_available_tools()}
47
- AlitaGitHubToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
48
44
  return create_model(
49
45
  name,
50
46
  __config__=ConfigDict(
@@ -57,12 +53,11 @@ class AlitaGitHubToolkit(BaseToolkit):
57
53
  },
58
54
  }
59
55
  ),
60
- github_configuration=(Optional[GithubConfiguration], Field(description="Github configuration", default=None,
61
- json_schema_extra={'configuration_types': ['github']})),
56
+ github_configuration=(GithubConfiguration, Field(description="Github configuration",
57
+ json_schema_extra={'configuration_types': ['github']})),
62
58
  pgvector_configuration=(Optional[PgVectorConfiguration], Field(description="PgVector configuration", default=None,
63
59
  json_schema_extra={'configuration_types': ['pgvector']})),
64
- repository=(str, Field(description="Github repository", json_schema_extra={'toolkit_name': True,
65
- 'max_toolkit_length': AlitaGitHubToolkit.toolkit_max_length})),
60
+ repository=(str, Field(description="Github repository")),
66
61
  active_branch=(Optional[str], Field(description="Active branch", default="main")),
67
62
  base_branch=(Optional[str], Field(description="Github Base branch", default="main")),
68
63
  # embedder settings
@@ -72,6 +67,7 @@ class AlitaGitHubToolkit(BaseToolkit):
72
67
  )
73
68
 
74
69
  @classmethod
70
+ @filter_missconfigured_index_tools
75
71
  def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
76
72
  if selected_tools is None:
77
73
  selected_tools = []
@@ -85,18 +81,22 @@ class AlitaGitHubToolkit(BaseToolkit):
85
81
  github_api_wrapper = AlitaGitHubAPIWrapper(**wrapper_payload)
86
82
  available_tools: List[Dict] = github_api_wrapper.get_available_tools()
87
83
  tools = []
88
- prefix = clean_string(toolkit_name, AlitaGitHubToolkit.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
89
84
  for tool in available_tools:
90
85
  if selected_tools:
91
86
  if tool["name"] not in selected_tools:
92
87
  continue
88
+ description = tool["description"]
89
+ if toolkit_name:
90
+ description = f"Toolkit: {toolkit_name}\n{description}"
91
+ description = f"Repository: {github_api_wrapper.github_repository}\n{description}"
92
+ description = description[:1000]
93
93
  tools.append(GitHubAction(
94
94
  api_wrapper=github_api_wrapper,
95
- name=prefix + tool["name"],
95
+ name=tool["name"],
96
96
  mode=tool["mode"],
97
- # set unique description for declared tools to differentiate the same methods for different toolkits
98
- description=f"Repository: {github_api_wrapper.github_repository}\n" + tool["description"],
99
- args_schema=tool["args_schema"]
97
+ description=description,
98
+ args_schema=tool["args_schema"],
99
+ metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
100
100
  ))
101
101
  return cls(tools=tools)
102
102
 
@@ -1,9 +1,7 @@
1
- from typing import Any, Dict, List, Optional, Union, Tuple
2
1
  import logging
3
- import traceback
4
- import json
5
- import re
6
- from pydantic import BaseModel, model_validator, Field, SecretStr
2
+ from typing import Any, Dict, Optional
3
+
4
+ from pydantic import model_validator, Field, SecretStr
7
5
 
8
6
  from .github_client import GitHubClient
9
7
  from .graphql_client_wrapper import GraphQLClientWrapper
@@ -11,28 +9,17 @@ from .schemas import (
11
9
  GitHubAuthConfig,
12
10
  GitHubRepoConfig
13
11
  )
14
-
15
- from ..elitea_base import BaseCodeToolApiWrapper
16
-
17
- from langchain_core.callbacks import dispatch_custom_event
12
+ from ..code_indexer_toolkit import CodeIndexerToolkit
13
+ from ..utils.available_tools_decorator import extend_with_parent_available_tools
18
14
 
19
15
  logger = logging.getLogger(__name__)
20
16
 
21
17
  # Import prompts for tools
22
- from .tool_prompts import (
23
- UPDATE_FILE_PROMPT,
24
- CREATE_ISSUE_PROMPT,
25
- UPDATE_ISSUE_PROMPT,
26
- CREATE_ISSUE_ON_PROJECT_PROMPT,
27
- UPDATE_ISSUE_ON_PROJECT_PROMPT
28
- )
29
18
 
30
19
  # Create schema models for the new indexing functionality
31
- from pydantic import create_model
32
- from typing import Literal
33
20
 
34
21
 
35
- class AlitaGitHubAPIWrapper(BaseCodeToolApiWrapper):
22
+ class AlitaGitHubAPIWrapper(CodeIndexerToolkit):
36
23
  """
37
24
  Wrapper for GitHub API that integrates both REST and GraphQL functionality.
38
25
  """
@@ -117,7 +104,7 @@ class AlitaGitHubAPIWrapper(BaseCodeToolApiWrapper):
117
104
  if "llm" not in values:
118
105
  values["llm"] = None
119
106
 
120
- return values
107
+ return super().validate_toolkit(values)
121
108
 
122
109
  # Expose GitHub REST client methods directly via property
123
110
  @property
@@ -131,7 +118,7 @@ class AlitaGitHubAPIWrapper(BaseCodeToolApiWrapper):
131
118
  """Access to GitHub GraphQL client methods"""
132
119
  return self.graphql_client_instance
133
120
 
134
-
121
+ @extend_with_parent_available_tools
135
122
  def get_available_tools(self):
136
123
  # this is horrible, I need to think on something better
137
124
  if not self.github_client_instance:
@@ -142,12 +129,8 @@ class AlitaGitHubAPIWrapper(BaseCodeToolApiWrapper):
142
129
  graphql_tools = GraphQLClientWrapper.model_construct().get_available_tools()
143
130
  else:
144
131
  graphql_tools = self.graphql_client_instance.get_available_tools()
145
-
146
- # Add vector search tools from base class (includes index_data + search tools)
147
- vector_search_tools = self._get_vector_search_tools()
148
132
 
149
- tools = github_tools + graphql_tools + vector_search_tools
150
- return tools
133
+ return github_tools + graphql_tools
151
134
 
152
135
  def _get_files(self, path: str = "", branch: str = None):
153
136
  """Get list of files from GitHub repository."""
@@ -11,6 +11,7 @@ from github import Auth, Github, GithubIntegration, Repository
11
11
  from github.Consts import DEFAULT_BASE_URL
12
12
  from langchain_core.tools import ToolException
13
13
 
14
+ from ..elitea_base import extend_with_file_operations, BaseCodeToolApiWrapper
14
15
  from .schemas import (
15
16
  GitHubAuthConfig,
16
17
  GitHubRepoConfig,
@@ -87,7 +88,6 @@ class GitHubClient(BaseModel):
87
88
 
88
89
  # Using optional variables with None defaults instead of PrivateAttr
89
90
  github_api: Optional[Github] = Field(default=None, exclude=True)
90
- github_repo_instance: Optional[Repository.Repository] = Field(default=None, exclude=True)
91
91
 
92
92
  # Adding auth config and repo config as optional fields for initialization
93
93
  auth_config: Optional[GitHubAuthConfig] = Field(default=None, exclude=True)
@@ -95,6 +95,25 @@ class GitHubClient(BaseModel):
95
95
 
96
96
  # Alita instance
97
97
  alita: Optional[Any] = Field(default=None, exclude=True)
98
+
99
+ # Import file operation methods from BaseCodeToolApiWrapper
100
+ read_file_chunk = BaseCodeToolApiWrapper.read_file_chunk
101
+ read_multiple_files = BaseCodeToolApiWrapper.read_multiple_files
102
+ search_file = BaseCodeToolApiWrapper.search_file
103
+ edit_file = BaseCodeToolApiWrapper.edit_file
104
+
105
+ @property
106
+ def github_repo_instance(self) -> Optional[Repository.Repository]:
107
+ if not hasattr(self, "_github_repo_instance") or self._github_repo_instance is None:
108
+ try:
109
+ if self.github_api and self.github_repository:
110
+ self._github_repo_instance = self.github_api.get_repo(self.github_repository)
111
+ else:
112
+ self._github_repo_instance = None
113
+ except Exception as e:
114
+ # Only raise when accessed, not during initialization
115
+ raise ToolException(e)
116
+ return self._github_repo_instance
98
117
 
99
118
  @model_validator(mode='before')
100
119
  def initialize_github_client(cls, values):
@@ -144,15 +163,6 @@ class GitHubClient(BaseModel):
144
163
  else:
145
164
  values["github_api"] = Github(base_url=values["github_base_url"], auth=auth)
146
165
 
147
- # Get repository instance
148
- if values.get("github_repository"):
149
- values["github_repo_instance"] = values["github_api"].get_repo(values["github_repository"])
150
- else:
151
- # Initialize with default authentication if no auth_config provided
152
- values["github_api"] = Github(base_url=values.get("github_base_url", DEFAULT_BASE_URL))
153
- if values.get("github_repository"):
154
- values["github_repo_instance"] = values["github_api"].get_repo(values["github_repository"])
155
-
156
166
  return values
157
167
 
158
168
  @staticmethod
@@ -1411,13 +1421,16 @@ class GitHubClient(BaseModel):
1411
1421
  except Exception as e:
1412
1422
  return f"File not found `{file_path}` on branch `{branch}`. Error: {str(e)}"
1413
1423
 
1414
- def _read_file(self, file_path: str, branch: str, repo_name: Optional[str] = None) -> str:
1424
+ def _read_file(self, file_path: str, branch: str, repo_name: Optional[str] = None, **kwargs) -> str:
1415
1425
  """
1416
- Read a file from specified branch
1426
+ Read a file from specified branch with optional partial read support.
1427
+
1417
1428
  Parameters:
1418
1429
  file_path(str): the file path
1419
1430
  branch(str): the branch to read the file from
1420
1431
  repo_name (Optional[str]): Name of the repository in format 'owner/repo'
1432
+ **kwargs: Additional parameters (offset, limit, head, tail) - currently ignored,
1433
+ partial read handled client-side by base class methods
1421
1434
 
1422
1435
  Returns:
1423
1436
  str: The file decoded as a string, or an error message if not found
@@ -1442,6 +1455,61 @@ class GitHubClient(BaseModel):
1442
1455
  str: The file contents as a string
1443
1456
  """
1444
1457
  return self._read_file(file_path, branch if branch else self.active_branch, repo_name)
1458
+
1459
+ def _write_file(
1460
+ self,
1461
+ file_path: str,
1462
+ content: str,
1463
+ branch: str = None,
1464
+ commit_message: str = None,
1465
+ repo_name: Optional[str] = None
1466
+ ) -> str:
1467
+ """
1468
+ Write content to a file (create or update).
1469
+
1470
+ Parameters:
1471
+ file_path: Path to the file
1472
+ content: New file content
1473
+ branch: Branch name (uses active branch if None)
1474
+ commit_message: Commit message
1475
+ repo_name: Name of the repository in format 'owner/repo'
1476
+
1477
+ Returns:
1478
+ Success message
1479
+ """
1480
+ try:
1481
+ repo = self.github_api.get_repo(repo_name) if repo_name else self.github_repo_instance
1482
+ branch = branch or self.active_branch
1483
+
1484
+ if branch == self.github_base_branch:
1485
+ raise ToolException(
1486
+ f"Cannot commit directly to the {self.github_base_branch} branch. "
1487
+ "Please create a new branch and try again."
1488
+ )
1489
+
1490
+ # Check if file exists
1491
+ try:
1492
+ existing_file = repo.get_contents(file_path, ref=branch)
1493
+ # File exists, update it
1494
+ repo.update_file(
1495
+ path=file_path,
1496
+ message=commit_message or f"Update {file_path}",
1497
+ content=content,
1498
+ branch=branch,
1499
+ sha=existing_file.sha,
1500
+ )
1501
+ return f"Updated file {file_path}"
1502
+ except:
1503
+ # File doesn't exist, create it
1504
+ repo.create_file(
1505
+ path=file_path,
1506
+ message=commit_message or f"Create {file_path}",
1507
+ content=content,
1508
+ branch=branch,
1509
+ )
1510
+ return f"Created file {file_path}"
1511
+ except Exception as e:
1512
+ raise ToolException(f"Unable to write file {file_path}: {str(e)}")
1445
1513
 
1446
1514
  def loader(self,
1447
1515
  branch: Optional[str] = None,
@@ -1874,6 +1942,7 @@ class GitHubClient(BaseModel):
1874
1942
  import traceback
1875
1943
  return f"API call failed: {traceback.format_exc()}"
1876
1944
 
1945
+ @extend_with_file_operations
1877
1946
  def get_available_tools(self) -> List[Dict[str, Any]]:
1878
1947
  return [
1879
1948
  {
@@ -119,7 +119,8 @@ LoaderSchema = create_model(
119
119
  "LoaderSchema",
120
120
  branch=(Optional[str], Field(description="The branch to set as active. If None, the current active branch is used.", default=None)),
121
121
  whitelist=(Optional[List[str]], Field(description="A list of file extensions or paths to include. If None, all files are included.", default=None)),
122
- blacklist=(Optional[List[str]], Field(description="A list of file extensions or paths to exclude. If None, no files are excluded.", default=None))
122
+ blacklist=(Optional[List[str]], Field(description="A list of file extensions or paths to exclude. If None, no files are excluded.", default=None)),
123
+ progress_step=(Optional[int], Field(default=5, ge=0, le=100, description="Optional step size for progress reporting during indexing (0-100)"))
123
124
  )
124
125
 
125
126
  CreateIssueOnProject = 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()}"
@@ -7,17 +7,17 @@ from pydantic import create_model, BaseModel, ConfigDict
7
7
  from pydantic.fields import Field
8
8
 
9
9
  from .api_wrapper import GitLabAPIWrapper
10
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
10
+ from ..elitea_base import filter_missconfigured_index_tools
11
+ from ..utils import clean_string, get_max_toolkit_length
11
12
  from ...configurations.gitlab import GitlabConfiguration
12
13
  from ...configurations.pgvector import PgVectorConfiguration
13
14
 
14
15
  name = "gitlab"
15
16
 
16
17
 
17
- def get_tools(tool):
18
+ def get_toolkit(tool):
18
19
  return AlitaGitlabToolkit().get_toolkit(
19
20
  selected_tools=tool['settings'].get('selected_tools', []),
20
- url=tool['settings']['url'],
21
21
  repository=tool['settings']['repository'],
22
22
  branch=tool['settings']['branch'],
23
23
  gitlab_configuration=tool['settings']['gitlab_configuration'],
@@ -30,21 +30,22 @@ def get_tools(tool):
30
30
  embedding_model=tool['settings'].get('embedding_model'),
31
31
  vectorstore_type="PGVector",
32
32
  toolkit_name=tool.get('toolkit_name')
33
- ).get_tools()
33
+ )
34
+
35
+ def get_tools(tool):
36
+ return get_toolkit(tool).get_tools()
34
37
 
35
38
  class AlitaGitlabToolkit(BaseToolkit):
36
39
  tools: List[BaseTool] = []
37
- toolkit_max_length: int = 0
38
40
 
39
41
  @staticmethod
40
42
  def toolkit_config_schema() -> BaseModel:
41
43
  selected_tools = {x['name']: x['args_schema'].schema() for x in
42
44
  GitLabAPIWrapper.model_construct().get_available_tools()}
43
- AlitaGitlabToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
44
45
  return create_model(
45
46
  name,
46
- repository=(str, Field(description="GitLab repository", json_schema_extra={'toolkit_name': True, 'max_toolkit_length': AlitaGitlabToolkit.toolkit_max_length})),
47
- gitlab_configuration=(Optional[GitlabConfiguration], Field(description="GitLab configuration", json_schema_extra={'configuration_types': ['gitlab']})),
47
+ repository=(str, Field(description="GitLab repository")),
48
+ gitlab_configuration=(GitlabConfiguration, Field(description="GitLab configuration", json_schema_extra={'configuration_types': ['gitlab']})),
48
49
  branch=(str, Field(description="Main branch", default="main")),
49
50
  # indexer settings
50
51
  pgvector_configuration=(Optional[PgVectorConfiguration], Field(default = None,
@@ -64,6 +65,7 @@ class AlitaGitlabToolkit(BaseToolkit):
64
65
  )
65
66
 
66
67
  @classmethod
68
+ @filter_missconfigured_index_tools
67
69
  def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
68
70
  if selected_tools is None:
69
71
  selected_tools = []
@@ -75,19 +77,22 @@ class AlitaGitlabToolkit(BaseToolkit):
75
77
  **(kwargs.get('embedding_configuration') or {}),
76
78
  }
77
79
  gitlab_api_wrapper = GitLabAPIWrapper(**wrapper_payload)
78
- prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
79
80
  available_tools: List[Dict] = gitlab_api_wrapper.get_available_tools()
80
81
  tools = []
81
82
  for tool in available_tools:
82
83
  if selected_tools:
83
84
  if tool["name"] not in selected_tools:
84
85
  continue
85
-
86
+ description = tool["description"] + f"\nrepo: {gitlab_api_wrapper.repository}"
87
+ if toolkit_name:
88
+ description = f"{description}\nToolkit: {toolkit_name}"
89
+ description = description[:1000]
86
90
  tools.append(BaseAction(
87
91
  api_wrapper=gitlab_api_wrapper,
88
- name=prefix + tool["name"],
89
- description=tool["description"] + f"\nrepo: {gitlab_api_wrapper.repository}",
90
- args_schema=tool["args_schema"]
92
+ name=tool["name"],
93
+ description=description,
94
+ args_schema=tool["args_schema"],
95
+ metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
91
96
  ))
92
97
  return cls(tools=tools)
93
98