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
@@ -3,11 +3,13 @@ from typing import Dict, List, Literal, Optional
3
3
  from requests.auth import HTTPBasicAuth
4
4
 
5
5
  from .api_wrapper import BitbucketAPIWrapper
6
- from .tools import __all__
7
6
  from langchain_core.tools import BaseToolkit
8
7
  from langchain_core.tools import BaseTool
9
8
  from pydantic import BaseModel, Field, ConfigDict, create_model
10
- from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length, check_connection_response
9
+
10
+ from ..base.tool import BaseAction
11
+ from ..elitea_base import filter_missconfigured_index_tools
12
+ from ..utils import clean_string, get_max_toolkit_length, check_connection_response
11
13
  from ...configurations.bitbucket import BitbucketConfiguration
12
14
  from ...configurations.pgvector import PgVectorConfiguration
13
15
  import requests
@@ -16,10 +18,9 @@ import requests
16
18
  name = "bitbucket"
17
19
 
18
20
 
19
- def get_tools(tool):
21
+ def get_toolkit(tool):
20
22
  return AlitaBitbucketToolkit.get_toolkit(
21
23
  selected_tools=tool['settings'].get('selected_tools', []),
22
- url=tool['settings']['url'],
23
24
  project=tool['settings']['project'],
24
25
  repository=tool['settings']['repository'],
25
26
  bitbucket_configuration=tool['settings']['bitbucket_configuration'],
@@ -32,27 +33,26 @@ def get_tools(tool):
32
33
  doctype='code',
33
34
  embedding_model=tool['settings'].get('embedding_model'),
34
35
  toolkit_name=tool.get('toolkit_name')
35
- ).get_tools()
36
+ )
37
+
38
+ def get_tools(tool):
39
+ return get_toolkit(tool).get_tools()
36
40
 
37
41
 
38
42
  class AlitaBitbucketToolkit(BaseToolkit):
39
43
  tools: List[BaseTool] = []
40
- toolkit_max_length: int = 0
41
44
 
42
45
  @staticmethod
43
46
  def toolkit_config_schema() -> BaseModel:
44
- selected_tools = {}
45
- for t in __all__:
46
- default = t['tool'].__pydantic_fields__['args_schema'].default
47
- selected_tools[t['name']] = default.schema() if default else default
48
- AlitaBitbucketToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
47
+ selected_tools = {x['name']: x['args_schema'].schema() for x in
48
+ BitbucketAPIWrapper.model_construct().get_available_tools()}
49
49
  m = create_model(
50
50
  name,
51
- project=(str, Field(description="Project/Workspace", json_schema_extra={'configuration': True})),
52
- repository=(str, Field(description="Repository", json_schema_extra={'max_toolkit_length': AlitaBitbucketToolkit.toolkit_max_length, 'configuration': True})),
51
+ project=(str, Field(description="Project/Workspace")),
52
+ repository=(str, Field(description="Repository")),
53
53
  branch=(str, Field(description="Main branch", default="main")),
54
54
  cloud=(Optional[bool], Field(description="Hosting Option", default=None)),
55
- bitbucket_configuration=(Optional[BitbucketConfiguration], Field(description="Bitbucket Configuration", json_schema_extra={'configuration_types': ['bitbucket']})),
55
+ bitbucket_configuration=(BitbucketConfiguration, Field(description="Bitbucket Configuration", json_schema_extra={'configuration_types': ['bitbucket']})),
56
56
  pgvector_configuration=(Optional[PgVectorConfiguration], Field(default=None, description="PgVector Configuration", json_schema_extra={'configuration_types': ['pgvector']})),
57
57
  # embedder settings
58
58
  embedding_model=(Optional[str], Field(default=None, description="Embedding configuration.", json_schema_extra={'configuration_model': 'embedding'})),
@@ -86,6 +86,7 @@ class AlitaBitbucketToolkit(BaseToolkit):
86
86
  return m
87
87
 
88
88
  @classmethod
89
+ @filter_missconfigured_index_tools
89
90
  def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
90
91
  if selected_tools is None:
91
92
  selected_tools = []
@@ -98,16 +99,23 @@ class AlitaBitbucketToolkit(BaseToolkit):
98
99
  **(kwargs.get('pgvector_configuration') or {}),
99
100
  }
100
101
  bitbucket_api_wrapper = BitbucketAPIWrapper(**wrapper_payload)
101
- available_tools: List[Dict] = __all__
102
- prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
102
+ available_tools: List[Dict] = bitbucket_api_wrapper.get_available_tools()
103
103
  tools = []
104
104
  for tool in available_tools:
105
105
  if selected_tools:
106
106
  if tool['name'] not in selected_tools:
107
107
  continue
108
- initiated_tool = tool['tool'](api_wrapper=bitbucket_api_wrapper)
109
- initiated_tool.name = prefix + tool['name']
110
- tools.append(initiated_tool)
108
+ description = tool["description"] + f"\nrepo: {bitbucket_api_wrapper.repository}"
109
+ if toolkit_name:
110
+ description = f"{description}\nToolkit: {toolkit_name}"
111
+ description = description[:1000]
112
+ tools.append(BaseAction(
113
+ api_wrapper=bitbucket_api_wrapper,
114
+ name=tool["name"],
115
+ description=description,
116
+ args_schema=tool["args_schema"],
117
+ metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
118
+ ))
111
119
  return cls(tools=tools)
112
120
 
113
121
  def get_tools(self):
@@ -2,28 +2,134 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import logging
5
- from typing import TYPE_CHECKING, Any, Dict, List, Optional
5
+ from typing import Any, Dict, List, Optional
6
+ import fnmatch
6
7
 
7
8
  from langchain_core.tools import ToolException
8
- from pydantic import model_validator, SecretStr
9
+ from pydantic import model_validator, SecretStr, create_model, Field
9
10
  from .bitbucket_constants import create_pr_data
10
11
  from .cloud_api_wrapper import BitbucketCloudApi, BitbucketServerApi
11
12
  from pydantic.fields import PrivateAttr
12
13
 
13
- from ..elitea_base import BaseCodeToolApiWrapper
14
+ from ..code_indexer_toolkit import CodeIndexerToolkit
15
+ from ..utils.available_tools_decorator import extend_with_parent_available_tools
16
+ from ..elitea_base import extend_with_file_operations, BaseCodeToolApiWrapper
14
17
 
15
18
  logger = logging.getLogger(__name__)
16
19
 
20
+ # Pydantic model definitions for tool arguments
21
+ CreateBranchModel = create_model(
22
+ "CreateBranchModel",
23
+ branch_name=(str, Field(description="The name of the branch, e.g. `my_branch`.")),
24
+ )
17
25
 
18
- if TYPE_CHECKING:
19
- pass
26
+ CreatePullRequestModel = create_model(
27
+ "CreatePullRequestModel",
28
+ pr_json_data=(str, Field(description=create_pr_data)),
29
+ )
20
30
 
31
+ CreateFileModel = create_model(
32
+ "CreateFileModel",
33
+ file_path=(str, Field(description="The path of the file")),
34
+ file_contents=(str, Field(description="The contents of the file")),
35
+ branch=(str, Field(description="The branch to create the file in")),
36
+ )
21
37
 
22
- class BitbucketAPIWrapper(BaseCodeToolApiWrapper):
38
+ UpdateFileModel = create_model(
39
+ "UpdateFileModel",
40
+ file_path=(str, Field(description="The path of the file")),
41
+ update_query=(str, Field(description="Contains the file contents required to be updated. "
42
+ "The old file contents is wrapped in OLD <<<< and >>>> OLD. "
43
+ "The new file contents is wrapped in NEW <<<< and >>>> NEW")),
44
+ branch=(str, Field(description="The branch to update the file in")),
45
+ )
46
+
47
+ ReadFileModel = create_model(
48
+ "ReadFileModel",
49
+ file_path=(str, Field(description="The path of the file")),
50
+ branch=(str, Field(description="The branch to read the file from")),
51
+ )
52
+
53
+ SetActiveBranchModel = create_model(
54
+ "SetActiveBranchModel",
55
+ branch_name=(str, Field(description="The name of the branch, e.g. `my_branch`.")),
56
+ )
57
+
58
+ ListBranchesInRepoModel = create_model(
59
+ "ListBranchesInRepoModel",
60
+ limit=(Optional[int], Field(default=20, description="Maximum number of branches to return. If not provided, all branches will be returned.")),
61
+ branch_wildcard=(Optional[str], Field(default=None, description="Wildcard pattern to filter branches by name. If not provided, all branches will be returned."))
62
+ )
63
+
64
+ ListFilesModel = create_model(
65
+ "ListFilesModel",
66
+ path=(Optional[str], Field(description="The path to list files from", default=None)),
67
+ recursive=(bool, Field(description="Whether to list files recursively", default=True)),
68
+ branch=(Optional[str], Field(description="The branch to list files from")),
69
+ )
70
+
71
+ GetPullRequestsCommitsModel = create_model(
72
+ "GetPullRequestsCommitsModel",
73
+ pr_id=(str, Field(description="The ID of the pull request to get commits from")),
74
+ )
75
+
76
+ GetPullRequestModel = create_model(
77
+ "GetPullRequestModel",
78
+ pr_id=(str, Field(description="The ID of the pull request to get details from")),
79
+ )
80
+
81
+ GetPullRequestsChangesModel = create_model(
82
+ "GetPullRequestsChangesModel",
83
+ pr_id=(str, Field(description="The ID of the pull request to get changes from")),
84
+ )
85
+
86
+ AddPullRequestCommentModel = create_model(
87
+ "AddPullRequestCommentModel",
88
+ pr_id=(str, Field(description="The ID of the pull request to add a comment to")),
89
+ content=(str, Field(description="The comment content")),
90
+ inline=(Optional[dict], Field(default=None, description="Inline comment details. Example: {'from': 57, 'to': 122, 'path': '<string>'}"))
91
+ )
92
+
93
+ DeleteFileModel = create_model(
94
+ "DeleteFileModel",
95
+ file_path=(str, Field(description="The path of the file")),
96
+ branch=(str, Field(description="The branch to delete the file from")),
97
+ commit_message=(str, Field(default=None, description="Commit message for deleting the file. Optional.")),
98
+ )
99
+
100
+ AppendFileModel = create_model(
101
+ "AppendFileModel",
102
+ file_path=(str, Field(description="The path of the file")),
103
+ content=(str, Field(description="The content to append to the file")),
104
+ branch=(str, Field(description="The branch to append the file in")),
105
+ )
106
+
107
+ GetIssuesModel = create_model(
108
+ "GetIssuesModel",
109
+ )
110
+
111
+ GetIssueModel = create_model(
112
+ "GetIssueModel",
113
+ issue_number=(int, Field(description="The number of the issue")),
114
+ )
115
+
116
+ CommentOnIssueModel = create_model(
117
+ "CommentOnIssueModel",
118
+ comment_query=(str, Field(description="The comment query string")),
119
+ )
120
+
121
+
122
+ class BitbucketAPIWrapper(CodeIndexerToolkit):
23
123
  """Wrapper for Bitbucket API."""
24
124
 
25
125
  _bitbucket: Any = PrivateAttr()
26
126
  _active_branch: Any = PrivateAttr()
127
+
128
+ # Import file operation methods from BaseCodeToolApiWrapper
129
+ read_file_chunk = BaseCodeToolApiWrapper.read_file_chunk
130
+ read_multiple_files = BaseCodeToolApiWrapper.read_multiple_files
131
+ search_file = BaseCodeToolApiWrapper.search_file
132
+ edit_file = BaseCodeToolApiWrapper.edit_file
27
133
  url: str = ''
28
134
  project: str = ''
29
135
  """The key of the project this repo belongs to"""
@@ -41,18 +147,6 @@ class BitbucketAPIWrapper(BaseCodeToolApiWrapper):
41
147
  """Bitbucket installation type: true for cloud, false for server.
42
148
  """
43
149
 
44
- llm: Optional[Any] = None
45
- # Alita instance
46
- alita: Optional[Any] = None
47
-
48
- # Vector store configuration
49
- connection_string: Optional[SecretStr] = None
50
- collection_name: Optional[str] = None
51
- doctype: Optional[str] = 'code'
52
- embedding_model: Optional[str] = "HuggingFaceEmbeddings"
53
- embedding_model_params: Optional[Dict[str, Any]] = {"model_name": "sentence-transformers/all-MiniLM-L6-v2"}
54
- vectorstore_type: Optional[str] = "PGVector"
55
-
56
150
  @model_validator(mode='before')
57
151
  @classmethod
58
152
  def validate_env(cls, values: Dict) -> Dict:
@@ -81,16 +175,36 @@ class BitbucketAPIWrapper(BaseCodeToolApiWrapper):
81
175
  repository=values['repository']
82
176
  )
83
177
  cls._active_branch = values.get('branch')
84
- return values
178
+ return super().validate_toolkit(values)
85
179
 
86
- def set_active_branch(self, branch: str) -> None:
180
+ def set_active_branch(self, branch_name: str) -> str:
87
181
  """Set the active branch for the bot."""
88
- self._active_branch = branch
89
- return f"Active branch set to `{branch}`"
182
+ self._active_branch = branch_name
183
+ return f"Active branch set to `{branch_name}`"
184
+
185
+ def list_branches_in_repo(self, limit: Optional[int] = 20, branch_wildcard: Optional[str] = None) -> List[str]:
186
+ """
187
+ Lists branches in the repository with optional limit and wildcard filtering.
188
+
189
+ Parameters:
190
+ limit (Optional[int]): Maximum number of branches to return
191
+ branch_wildcard (Optional[str]): Wildcard pattern to filter branches (e.g., '*dev')
192
+
193
+ Returns:
194
+ List[str]: List containing names of branches
195
+ """
196
+ try:
197
+ branches = self._bitbucket.list_branches()
198
+
199
+ if branch_wildcard:
200
+ branches = [branch for branch in branches if fnmatch.fnmatch(branch, branch_wildcard)]
90
201
 
91
- def list_branches_in_repo(self) -> List[str]:
92
- """List all branches in the repository."""
93
- return self._bitbucket.list_branches()
202
+ if limit is not None:
203
+ branches = branches[:limit]
204
+
205
+ return "Found branches: " + ", ".join(branches)
206
+ except Exception as e:
207
+ return f"Failed to list branches: {str(e)}"
94
208
 
95
209
  def create_branch(self, branch_name: str) -> None:
96
210
  """Create a new branch in the repository."""
@@ -253,12 +367,15 @@ class BitbucketAPIWrapper(BaseCodeToolApiWrapper):
253
367
  # except Exception as e:
254
368
  # raise ToolException(f"Can't extract file commit hash (`{file_path}`) due to error:\n{str(e)}")
255
369
 
256
- def _read_file(self, file_path: str, branch: str) -> str:
370
+ def _read_file(self, file_path: str, branch: str, **kwargs) -> str:
257
371
  """
258
- Reads a file from the gitlab repo
372
+ Reads a file from the bitbucket repo with optional partial read support.
373
+
259
374
  Parameters:
260
375
  file_path(str): the file path
261
376
  branch(str): branch name (by default: active_branch)
377
+ **kwargs: Additional parameters (offset, limit, head, tail) - currently ignored,
378
+ partial read handled client-side by base class methods
262
379
  Returns:
263
380
  str: The file decoded as a string
264
381
  """
@@ -266,3 +383,144 @@ class BitbucketAPIWrapper(BaseCodeToolApiWrapper):
266
383
  return self._bitbucket.get_file(file_path=file_path, branch=branch)
267
384
  except Exception as e:
268
385
  raise ToolException(f"Can't extract file content (`{file_path}`) due to error:\n{str(e)}")
386
+
387
+ def list_files(self, path: str = None, recursive: bool = True, branch: str = None) -> List[str]:
388
+ """List files in the repository with optional path, recursive search, and branch."""
389
+ branch = branch if branch else self._active_branch
390
+ try:
391
+ files_str = self._get_files(path, branch)
392
+ # Parse the string response to extract file paths
393
+ # This is a simplified implementation - might need adjustment based on actual response format
394
+ import ast
395
+ try:
396
+ files_list = ast.literal_eval(files_str)
397
+ if isinstance(files_list, list):
398
+ return files_list
399
+ else:
400
+ return [str(files_list)]
401
+ except:
402
+ return [files_str] if files_str else []
403
+ except Exception as e:
404
+ return f"Failed to list files: {str(e)}"
405
+
406
+ def read_file(self, file_path: str, branch: str) -> str:
407
+ """Read the contents of a file in the repository."""
408
+ try:
409
+ return self._read_file(file_path, branch)
410
+ except Exception as e:
411
+ return f"Failed to read file {file_path}: {str(e)}"
412
+
413
+ def _write_file(
414
+ self,
415
+ file_path: str,
416
+ content: str,
417
+ branch: str = None,
418
+ commit_message: str = None
419
+ ) -> str:
420
+ """
421
+ Write content to a file (create or update).
422
+
423
+ Parameters:
424
+ file_path: Path to the file
425
+ content: New file content
426
+ branch: Branch name (uses active branch if None)
427
+ commit_message: Commit message (not used by Bitbucket API)
428
+
429
+ Returns:
430
+ Success message
431
+ """
432
+ try:
433
+ branch = branch or self._active_branch
434
+
435
+ # Check if file exists by attempting to read it
436
+ try:
437
+ self._read_file(file_path, branch)
438
+ # File exists, update it using OLD/NEW format
439
+ old_content = self._read_file(file_path, branch)
440
+ update_query = f"OLD <<<<\n{old_content}\n>>>> OLD\nNEW <<<<\n{content}\n>>>> NEW"
441
+ self._bitbucket.update_file(file_path=file_path, update_query=update_query, branch=branch)
442
+ return f"Updated file {file_path}"
443
+ except:
444
+ # File doesn't exist, create it
445
+ self._bitbucket.create_file(file_path=file_path, file_contents=content, branch=branch)
446
+ return f"Created file {file_path}"
447
+ except Exception as e:
448
+ raise ToolException(f"Unable to write file {file_path}: {str(e)}")
449
+
450
+ @extend_with_parent_available_tools
451
+ @extend_with_file_operations
452
+ def get_available_tools(self):
453
+ return [
454
+ {
455
+ "name": "create_branch",
456
+ "ref": self.create_branch,
457
+ "description": self.create_branch.__doc__ or "Create a new branch in the repository.",
458
+ "args_schema": CreateBranchModel,
459
+ },
460
+ {
461
+ "name": "list_branches_in_repo",
462
+ "ref": self.list_branches_in_repo,
463
+ "description": self.list_branches_in_repo.__doc__ or "List branches in the repository with optional limit and wildcard filtering.",
464
+ "args_schema": ListBranchesInRepoModel,
465
+ },
466
+ {
467
+ "name": "list_files",
468
+ "ref": self.list_files,
469
+ "description": self.list_files.__doc__ or "List files in the repository with optional path, recursive search, and branch.",
470
+ "args_schema": ListFilesModel,
471
+ },
472
+ {
473
+ "name": "create_pull_request",
474
+ "ref": self.create_pull_request,
475
+ "description": self.create_pull_request.__doc__ or "Create a pull request in the repository.",
476
+ "args_schema": CreatePullRequestModel,
477
+ },
478
+ {
479
+ "name": "create_file",
480
+ "ref": self.create_file,
481
+ "description": self.create_file.__doc__ or "Create a new file in the repository.",
482
+ "args_schema": CreateFileModel,
483
+ },
484
+ {
485
+ "name": "read_file",
486
+ "ref": self.read_file,
487
+ "description": self.read_file.__doc__ or "Read the contents of a file in the repository.",
488
+ "args_schema": ReadFileModel,
489
+ },
490
+ {
491
+ "name": "update_file",
492
+ "ref": self.update_file,
493
+ "description": self.update_file.__doc__ or "Update the contents of a file in the repository.",
494
+ "args_schema": UpdateFileModel,
495
+ },
496
+ {
497
+ "name": "set_active_branch",
498
+ "ref": self.set_active_branch,
499
+ "description": self.set_active_branch.__doc__ or "Set the active branch in the repository.",
500
+ "args_schema": SetActiveBranchModel,
501
+ },
502
+ {
503
+ "name": "get_pull_requests_commits",
504
+ "ref": self.get_pull_requests_commits,
505
+ "description": self.get_pull_requests_commits.__doc__ or "Get commits from a pull request in the repository.",
506
+ "args_schema": GetPullRequestsCommitsModel,
507
+ },
508
+ {
509
+ "name": "get_pull_request",
510
+ "ref": self.get_pull_request,
511
+ "description": self.get_pull_request.__doc__ or "Get details of a pull request in the repository.",
512
+ "args_schema": GetPullRequestModel,
513
+ },
514
+ {
515
+ "name": "get_pull_requests_changes",
516
+ "ref": self.get_pull_requests_changes,
517
+ "description": self.get_pull_requests_changes.__doc__ or "Get changes from a pull request in the repository.",
518
+ "args_schema": GetPullRequestsChangesModel,
519
+ },
520
+ {
521
+ "name": "add_pull_request_comment",
522
+ "ref": self.add_pull_request_comment,
523
+ "description": self.add_pull_request_comment.__doc__ or "Add a comment to a pull request in the repository.",
524
+ "args_schema": AddPullRequestCommentModel,
525
+ }
526
+ ]
@@ -35,7 +35,7 @@ def normalize_response(response) -> Dict[str, Any]:
35
35
  class BitbucketApiAbstract(ABC):
36
36
 
37
37
  @abstractmethod
38
- def list_branches(self) -> str:
38
+ def list_branches(self) -> List[str]:
39
39
  pass
40
40
 
41
41
  @abstractmethod
@@ -86,9 +86,9 @@ class BitbucketServerApi(BitbucketApiAbstract):
86
86
  self.password = password
87
87
  self.api_client = Bitbucket(url=url, username=username, password=password)
88
88
 
89
- def list_branches(self) -> str:
89
+ def list_branches(self) -> List[str]:
90
90
  branches = self.api_client.get_branches(project_key=self.project, repository_slug=self.repository)
91
- return json.dumps([branch['displayId'] for branch in branches])
91
+ return [branch['displayId'] for branch in branches]
92
92
 
93
93
  def create_branch(self, branch_name: str, branch_from: str) -> Response:
94
94
  return self.api_client.create_branch(
@@ -257,10 +257,10 @@ class BitbucketCloudApi(BitbucketApiAbstract):
257
257
  except Exception as e:
258
258
  raise ToolException(f"Unable to connect to the repository '{self.repository_name}' due to error:\n{str(e)}")
259
259
 
260
- def list_branches(self) -> str:
260
+ def list_branches(self) -> List[str]:
261
261
  branches = self.repository.branches.each()
262
262
  branch_names = [branch.name for branch in branches]
263
- return ', '.join(branch_names)
263
+ return branch_names
264
264
 
265
265
  def _get_branch(self, branch_name: str) -> Response:
266
266
  return self.repository.branches.get(branch_name)
@@ -1,16 +1,19 @@
1
1
  from typing import List, Optional, Literal
2
2
  from langchain_core.tools import BaseTool, BaseToolkit
3
3
 
4
- from pydantic import create_model, BaseModel, ConfigDict, Field, SecretStr, model_validator
4
+ from pydantic import create_model, BaseModel, ConfigDict, Field, model_validator
5
5
 
6
6
  from langchain_community.utilities.google_search import GoogleSearchAPIWrapper
7
7
  from langchain_community.utilities.wikipedia import WikipediaAPIWrapper
8
8
  from .google_search_rag import GoogleSearchResults
9
9
  from .crawler import SingleURLCrawler, MultiURLCrawler, GetHTMLContent, GetPDFContent
10
10
  from .wiki import WikipediaQueryRun
11
- from ..utils import get_max_toolkit_length, clean_string, TOOLKIT_SPLITTER
11
+ from ..utils import get_max_toolkit_length, clean_string
12
+ from ...configurations.browser import BrowserConfiguration
12
13
  from logging import getLogger
13
14
 
15
+ from ...configurations.pgvector import PgVectorConfiguration
16
+
14
17
  logger = getLogger(__name__)
15
18
 
16
19
  name = "browser"
@@ -19,8 +22,9 @@ name = "browser"
19
22
  def get_tools(tool):
20
23
  return BrowserToolkit().get_toolkit(
21
24
  selected_tools=tool['settings'].get('selected_tools', []),
22
- google_api_key=tool['settings'].get('google_api_key'),
23
- google_cse_id=tool['settings'].get("google_cse_id"),
25
+ browser_configuration=tool['settings']['browser_configuration'],
26
+ pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
27
+ embedding_model=tool['settings'].get('embedding_model'),
24
28
  toolkit_name=tool.get('toolkit_name', '')
25
29
  ).get_tools()
26
30
 
@@ -38,22 +42,29 @@ class BrowserToolkit(BaseToolkit):
38
42
  'google': GoogleSearchResults.__pydantic_fields__['args_schema'].default.schema(),
39
43
  'wiki': WikipediaQueryRun.__pydantic_fields__['args_schema'].default.schema()
40
44
  }
41
- BrowserToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
42
45
 
43
46
  def validate_google_fields(cls, values):
44
47
  if 'google' in values.get('selected_tools', []):
45
- google_cse_id = values.get('google_cse_id') is not None
46
- google_api_key = values.get('google_api_key') is not None
48
+ browser_config = values.get('browser_configuration', {})
49
+ google_cse_id = browser_config.get('google_cse_id') is not None if browser_config else False
50
+ google_api_key = browser_config.get('google_api_key') is not None if browser_config else False
47
51
  if not (google_cse_id and google_api_key):
48
52
  raise ValueError("google_cse_id and google_api_key are required when 'google' is in selected_tools")
49
53
  return values
50
54
 
51
55
  return create_model(
52
56
  name,
53
- __config__=ConfigDict(json_schema_extra={'metadata': {"label": "Browser", "icon_url": None, "categories": ["testing"], "extra_categories": ["web scraping", "search", "crawler"]}}),
54
- google_cse_id=(Optional[str], Field(description="Google CSE id", default=None)),
55
- google_api_key=(Optional[SecretStr],
56
- Field(description="Google API key", default=None, json_schema_extra={'secret': True})),
57
+ __config__=ConfigDict(json_schema_extra={'metadata': {"label": "Browser", "icon_url": None,
58
+ "categories": ["testing"],
59
+ "extra_categories": [
60
+ "web scraping", "search", "crawler"
61
+ ]}}),
62
+ browser_configuration=(Optional[BrowserConfiguration],
63
+ Field(description="Browser Configuration (required for tools and `google`)",
64
+ default=None, json_schema_extra={'configuration_types': ['browser']})),
65
+ pgvector_configuration=(Optional[PgVectorConfiguration],
66
+ Field(description="PgVector configuration (required for tools `multi_url_crawler`)",
67
+ default=None, json_schema_extra={'configuration_types': ['pgvector']})),
57
68
  selected_tools=(List[Literal[tuple(selected_tools)]],
58
69
  Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
59
70
  __validators__={
@@ -65,8 +76,19 @@ class BrowserToolkit(BaseToolkit):
65
76
  def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
66
77
  if selected_tools is None:
67
78
  selected_tools = []
79
+
80
+ wrapper_payload_google = {
81
+ **kwargs,
82
+ **kwargs.get('browser_configuration', {}),
83
+ **kwargs.get('pgvector_configuration', {}),
84
+ }
85
+
86
+ wrapper_payload_rag_based = {
87
+ **kwargs,
88
+ **kwargs.get('pgvector_configuration', {}),
89
+ }
90
+
68
91
  tools = []
69
- prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
70
92
  if not selected_tools:
71
93
  selected_tools = [
72
94
  'single_url_crawler',
@@ -80,7 +102,7 @@ class BrowserToolkit(BaseToolkit):
80
102
  if tool == 'single_url_crawler':
81
103
  tool_entry = SingleURLCrawler()
82
104
  elif tool == 'multi_url_crawler':
83
- tool_entry = MultiURLCrawler()
105
+ tool_entry = MultiURLCrawler(**wrapper_payload_rag_based)
84
106
  elif tool == 'get_html_content':
85
107
  tool_entry = GetHTMLContent()
86
108
  elif tool == 'get_pdf_content':
@@ -88,8 +110,8 @@ class BrowserToolkit(BaseToolkit):
88
110
  elif tool == 'google':
89
111
  try:
90
112
  google_api_wrapper = GoogleSearchAPIWrapper(
91
- google_api_key=kwargs.get("google_api_key"),
92
- google_cse_id=kwargs.get("google_cse_id"),
113
+ google_api_key=wrapper_payload_google.get('google_api_key'),
114
+ google_cse_id=wrapper_payload_google.get('google_cse_id')
93
115
  )
94
116
  tool_entry = GoogleSearchResults(api_wrapper=google_api_wrapper)
95
117
  # rename the tool to avoid conflicts
@@ -103,7 +125,10 @@ class BrowserToolkit(BaseToolkit):
103
125
 
104
126
  # Only add the tool if it was successfully created
105
127
  if tool_entry is not None:
106
- tool_entry.name = f"{prefix}{tool_entry.name}"
128
+ if toolkit_name:
129
+ tool_entry.description = f"{tool_entry.description}\nToolkit: {toolkit_name}"
130
+ tool_entry.description = tool_entry.description[:1000]
131
+ tool_entry.metadata = {"toolkit_name": toolkit_name}
107
132
  tools.append(tool_entry)
108
133
  return cls(tools=tools)
109
134
 
@@ -27,13 +27,15 @@ class MultiURLCrawler(BaseTool):
27
27
  max_response_size: int = 3000
28
28
  name: str = "multi_url_crawler"
29
29
  description: str = "Crawls multiple URLs and returns the content related to query"
30
+ connection_string: str = None
30
31
  args_schema: Type[BaseModel] = create_model("MultiURLCrawlerModel",
31
32
  query=(str, Field(description="Query text to search pages")),
32
33
  urls=(list[str], Field(description="list of URLs to search like ['url1', 'url2']")))
33
34
 
34
35
  def _run(self, query: str, urls: list[str], run_manager=None):
35
36
  urls = [url.strip() for url in urls]
36
- return webRag(urls, self.max_response_size, query)
37
+ return webRag(urls=urls, max_response_size=self.max_response_size, query=query,
38
+ connection_string=self.connection_string)
37
39
 
38
40
 
39
41
  class GetHTMLContent(BaseTool):