alita-sdk 0.3.486__py3-none-any.whl → 0.3.515__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of alita-sdk might be problematic. Click here for more details.
- alita_sdk/cli/agent_loader.py +27 -6
- alita_sdk/cli/agents.py +10 -1
- alita_sdk/cli/inventory.py +12 -195
- alita_sdk/cli/tools/filesystem.py +95 -9
- alita_sdk/community/inventory/__init__.py +12 -0
- alita_sdk/community/inventory/toolkit.py +9 -5
- alita_sdk/community/inventory/toolkit_utils.py +176 -0
- alita_sdk/configurations/ado.py +144 -0
- alita_sdk/configurations/confluence.py +76 -42
- alita_sdk/configurations/figma.py +76 -0
- alita_sdk/configurations/gitlab.py +2 -0
- alita_sdk/configurations/qtest.py +72 -1
- alita_sdk/configurations/report_portal.py +96 -0
- alita_sdk/configurations/sharepoint.py +148 -0
- alita_sdk/configurations/testio.py +83 -0
- alita_sdk/runtime/clients/artifact.py +2 -2
- alita_sdk/runtime/clients/client.py +64 -40
- alita_sdk/runtime/clients/sandbox_client.py +14 -0
- alita_sdk/runtime/langchain/assistant.py +48 -2
- alita_sdk/runtime/langchain/constants.py +3 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +2 -1
- alita_sdk/runtime/langchain/document_loaders/constants.py +12 -7
- alita_sdk/runtime/langchain/langraph_agent.py +10 -10
- alita_sdk/runtime/langchain/utils.py +6 -1
- alita_sdk/runtime/toolkits/artifact.py +14 -5
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +94 -219
- alita_sdk/runtime/toolkits/planning.py +13 -6
- alita_sdk/runtime/toolkits/tools.py +60 -25
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/artifact.py +185 -23
- alita_sdk/runtime/tools/function.py +2 -1
- alita_sdk/runtime/tools/llm.py +155 -34
- alita_sdk/runtime/tools/mcp_remote_tool.py +25 -10
- alita_sdk/runtime/tools/mcp_server_tool.py +2 -4
- alita_sdk/runtime/tools/vectorstore_base.py +3 -3
- alita_sdk/runtime/utils/AlitaCallback.py +136 -21
- alita_sdk/runtime/utils/mcp_client.py +492 -0
- alita_sdk/runtime/utils/mcp_oauth.py +125 -8
- alita_sdk/runtime/utils/mcp_sse_client.py +35 -6
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/toolkit_utils.py +7 -13
- alita_sdk/runtime/utils/utils.py +2 -0
- alita_sdk/tools/__init__.py +15 -0
- alita_sdk/tools/ado/repos/__init__.py +10 -12
- alita_sdk/tools/ado/test_plan/__init__.py +23 -8
- alita_sdk/tools/ado/wiki/__init__.py +24 -8
- alita_sdk/tools/ado/wiki/ado_wrapper.py +21 -7
- alita_sdk/tools/ado/work_item/__init__.py +24 -8
- alita_sdk/tools/advanced_jira_mining/__init__.py +10 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +12 -9
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +9 -7
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +26 -1
- alita_sdk/tools/bitbucket/__init__.py +14 -10
- alita_sdk/tools/bitbucket/api_wrapper.py +50 -2
- alita_sdk/tools/browser/__init__.py +5 -4
- alita_sdk/tools/carrier/__init__.py +5 -6
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +2 -0
- alita_sdk/tools/chunkers/universal_chunker.py +1 -0
- alita_sdk/tools/cloud/aws/__init__.py +9 -7
- alita_sdk/tools/cloud/azure/__init__.py +9 -7
- alita_sdk/tools/cloud/gcp/__init__.py +9 -7
- alita_sdk/tools/cloud/k8s/__init__.py +9 -7
- alita_sdk/tools/code/linter/__init__.py +9 -8
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +9 -7
- alita_sdk/tools/confluence/__init__.py +15 -10
- alita_sdk/tools/confluence/api_wrapper.py +63 -14
- alita_sdk/tools/custom_open_api/__init__.py +11 -5
- alita_sdk/tools/elastic/__init__.py +10 -8
- alita_sdk/tools/elitea_base.py +387 -9
- alita_sdk/tools/figma/__init__.py +8 -7
- alita_sdk/tools/github/__init__.py +12 -14
- alita_sdk/tools/github/github_client.py +68 -2
- alita_sdk/tools/github/tool.py +5 -1
- alita_sdk/tools/gitlab/__init__.py +14 -11
- alita_sdk/tools/gitlab/api_wrapper.py +81 -1
- alita_sdk/tools/gitlab_org/__init__.py +9 -8
- alita_sdk/tools/google/bigquery/__init__.py +12 -12
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +9 -8
- alita_sdk/tools/jira/__init__.py +15 -10
- alita_sdk/tools/keycloak/__init__.py +10 -8
- alita_sdk/tools/localgit/__init__.py +8 -3
- alita_sdk/tools/localgit/local_git.py +62 -54
- alita_sdk/tools/localgit/tool.py +5 -1
- alita_sdk/tools/memory/__init__.py +11 -3
- alita_sdk/tools/ocr/__init__.py +10 -8
- alita_sdk/tools/openapi/__init__.py +6 -2
- alita_sdk/tools/pandas/__init__.py +9 -7
- alita_sdk/tools/postman/__init__.py +10 -11
- alita_sdk/tools/pptx/__init__.py +9 -9
- alita_sdk/tools/qtest/__init__.py +9 -8
- alita_sdk/tools/rally/__init__.py +9 -8
- alita_sdk/tools/report_portal/__init__.py +11 -9
- alita_sdk/tools/salesforce/__init__.py +9 -9
- alita_sdk/tools/servicenow/__init__.py +10 -8
- alita_sdk/tools/sharepoint/__init__.py +9 -8
- alita_sdk/tools/sharepoint/api_wrapper.py +2 -2
- alita_sdk/tools/slack/__init__.py +8 -7
- alita_sdk/tools/sql/__init__.py +9 -8
- alita_sdk/tools/testio/__init__.py +9 -8
- alita_sdk/tools/testrail/__init__.py +10 -8
- alita_sdk/tools/utils/__init__.py +9 -4
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +16 -18
- alita_sdk/tools/xray/__init__.py +10 -8
- alita_sdk/tools/yagmail/__init__.py +8 -3
- alita_sdk/tools/zephyr/__init__.py +8 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +10 -8
- alita_sdk/tools/zephyr_essential/__init__.py +9 -8
- alita_sdk/tools/zephyr_scale/__init__.py +9 -8
- alita_sdk/tools/zephyr_squad/__init__.py +9 -8
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/METADATA +1 -1
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/RECORD +124 -119
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/entry_points.txt +0 -0
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.486.dist-info → alita_sdk-0.3.515.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ from pydantic import create_model, BaseModel, Field, SecretStr
|
|
|
6
6
|
from .data_mining_wrapper import AdvancedJiraMiningWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
8
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ..utils import clean_string,
|
|
9
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
10
10
|
|
|
11
11
|
name = "advanced_jira_mining"
|
|
12
12
|
|
|
@@ -28,15 +28,13 @@ def get_tools(tool):
|
|
|
28
28
|
|
|
29
29
|
class AdvancedJiraMiningToolkit(BaseToolkit):
|
|
30
30
|
tools: List[BaseTool] = []
|
|
31
|
-
toolkit_max_length: int = 0
|
|
32
31
|
|
|
33
32
|
@staticmethod
|
|
34
33
|
def toolkit_config_schema() -> BaseModel:
|
|
35
34
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AdvancedJiraMiningWrapper.model_construct().get_available_tools()}
|
|
36
|
-
AdvancedJiraMiningToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
37
35
|
return create_model(
|
|
38
36
|
name,
|
|
39
|
-
jira_base_url=(str, Field(default="", title="Jira URL", description="Jira URL", json_schema_extra={'toolkit_name': True
|
|
37
|
+
jira_base_url=(str, Field(default="", title="Jira URL", description="Jira URL", json_schema_extra={'toolkit_name': True})),
|
|
40
38
|
confluence_base_url=(str, Field(default="", title="Confluence URL", description="Confluence URL")),
|
|
41
39
|
model_type=(str, Field(default="", title="Model type", description="Model type")),
|
|
42
40
|
summarization_prompt=(Optional[str], Field(default=None, title="Summarization prompt", description="Summarization prompt")),
|
|
@@ -66,17 +64,21 @@ class AdvancedJiraMiningToolkit(BaseToolkit):
|
|
|
66
64
|
selected_tools = []
|
|
67
65
|
jira_mining_wrapper = AdvancedJiraMiningWrapper(**kwargs)
|
|
68
66
|
available_tools = jira_mining_wrapper.get_available_tools()
|
|
69
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
70
67
|
tools = []
|
|
71
68
|
for tool in available_tools:
|
|
72
69
|
if selected_tools:
|
|
73
70
|
if tool["name"] not in selected_tools:
|
|
74
71
|
continue
|
|
72
|
+
description = tool["description"]
|
|
73
|
+
if toolkit_name:
|
|
74
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
75
|
+
description = description[:1000]
|
|
75
76
|
tools.append(BaseAction(
|
|
76
77
|
api_wrapper=jira_mining_wrapper,
|
|
77
|
-
name=
|
|
78
|
-
description=
|
|
79
|
-
args_schema=tool["args_schema"]
|
|
78
|
+
name=tool["name"],
|
|
79
|
+
description=description,
|
|
80
|
+
args_schema=tool["args_schema"],
|
|
81
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
80
82
|
))
|
|
81
83
|
return cls(tools=tools)
|
|
82
84
|
|
|
@@ -6,7 +6,7 @@ from langchain_core.tools import BaseTool, BaseToolkit
|
|
|
6
6
|
from pydantic import BaseModel, Field, computed_field, field_validator
|
|
7
7
|
|
|
8
8
|
from alita_sdk.configurations.delta_lake import DeltaLakeConfiguration
|
|
9
|
-
from ...utils import
|
|
9
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
10
10
|
from .api_wrapper import DeltaLakeApiWrapper
|
|
11
11
|
from .tool import DeltaLakeAction
|
|
12
12
|
|
|
@@ -21,10 +21,6 @@ def get_available_tools() -> dict[str, dict]:
|
|
|
21
21
|
}
|
|
22
22
|
return available_tools
|
|
23
23
|
|
|
24
|
-
toolkit_max_length = lru_cache(maxsize=1)(
|
|
25
|
-
lambda: get_max_toolkit_length(get_available_tools())
|
|
26
|
-
)
|
|
27
|
-
|
|
28
24
|
class DeltaLakeToolkitConfig(BaseModel):
|
|
29
25
|
class Config:
|
|
30
26
|
title = name
|
|
@@ -87,9 +83,10 @@ class DeltaLakeToolkit(BaseToolkit):
|
|
|
87
83
|
|
|
88
84
|
@computed_field
|
|
89
85
|
@property
|
|
90
|
-
def
|
|
86
|
+
def toolkit_context(self) -> str:
|
|
87
|
+
"""Returns toolkit context for descriptions (max 1000 chars)."""
|
|
91
88
|
return (
|
|
92
|
-
clean_string(self.toolkit_name,
|
|
89
|
+
f" [Toolkit: {clean_string(self.toolkit_name, 0)}]"
|
|
93
90
|
if self.toolkit_name
|
|
94
91
|
else ""
|
|
95
92
|
)
|
|
@@ -118,12 +115,18 @@ class DeltaLakeToolkit(BaseToolkit):
|
|
|
118
115
|
selected_tools = set(selected_tools)
|
|
119
116
|
for t in instance.available_tools:
|
|
120
117
|
if t["name"] in selected_tools:
|
|
118
|
+
description = t["description"]
|
|
119
|
+
if toolkit_name:
|
|
120
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
121
|
+
description = f"S3 Path: {getattr(instance.api_wrapper, 's3_path', '')} Table Path: {getattr(instance.api_wrapper, 'table_path', '')}\n{description}"
|
|
122
|
+
description = description[:1000]
|
|
121
123
|
instance.tools.append(
|
|
122
124
|
DeltaLakeAction(
|
|
123
125
|
api_wrapper=instance.api_wrapper,
|
|
124
|
-
name=
|
|
125
|
-
description=
|
|
126
|
+
name=t["name"],
|
|
127
|
+
description=description,
|
|
126
128
|
args_schema=t["args_schema"],
|
|
129
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
127
130
|
)
|
|
128
131
|
)
|
|
129
132
|
return instance
|
|
@@ -29,7 +29,11 @@ class DeltaLakeAction(BaseTool):
|
|
|
29
29
|
) -> str:
|
|
30
30
|
"""Use the Delta Lake API to run an operation."""
|
|
31
31
|
try:
|
|
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
|
+
tool_name = re.sub(r'_\d+$', '', self.name)
|
|
32
36
|
# Use the tool name to dispatch to the correct API wrapper method
|
|
33
|
-
return self.api_wrapper.run(
|
|
37
|
+
return self.api_wrapper.run(tool_name, *args, **kwargs)
|
|
34
38
|
except Exception as e:
|
|
35
39
|
return f"Error: {format_exc()}"
|
|
@@ -6,7 +6,7 @@ from langchain_core.tools import BaseToolkit, BaseTool
|
|
|
6
6
|
from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
7
7
|
|
|
8
8
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ...utils import clean_string,
|
|
9
|
+
from ...utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
10
10
|
from ....configurations.azure_search import AzureSearchConfiguration
|
|
11
11
|
import requests
|
|
12
12
|
|
|
@@ -31,12 +31,10 @@ def get_toolkit():
|
|
|
31
31
|
|
|
32
32
|
class AzureSearchToolkit(BaseToolkit):
|
|
33
33
|
tools: List[BaseTool] = []
|
|
34
|
-
toolkit_max_length: int = 0
|
|
35
34
|
|
|
36
35
|
@staticmethod
|
|
37
36
|
def toolkit_config_schema() -> BaseModel:
|
|
38
37
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AzureSearchApiWrapper.model_construct().get_available_tools()}
|
|
39
|
-
AzureSearchToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
40
38
|
m = create_model(
|
|
41
39
|
name,
|
|
42
40
|
index_name=(str, Field(description="Azure Search index name")),
|
|
@@ -79,17 +77,21 @@ class AzureSearchToolkit(BaseToolkit):
|
|
|
79
77
|
}
|
|
80
78
|
azure_search_api_wrapper = AzureSearchApiWrapper(**wrapper_payload)
|
|
81
79
|
available_tools = azure_search_api_wrapper.get_available_tools()
|
|
82
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
83
80
|
tools = []
|
|
84
81
|
for tool in available_tools:
|
|
85
82
|
if selected_tools:
|
|
86
83
|
if tool["name"] not in selected_tools:
|
|
87
84
|
continue
|
|
85
|
+
description = tool["description"]
|
|
86
|
+
if toolkit_name:
|
|
87
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
88
|
+
description = description[:1000]
|
|
88
89
|
tools.append(BaseAction(
|
|
89
90
|
api_wrapper=azure_search_api_wrapper,
|
|
90
|
-
name=
|
|
91
|
-
description=
|
|
92
|
-
args_schema=tool["args_schema"]
|
|
91
|
+
name=tool["name"],
|
|
92
|
+
description=description,
|
|
93
|
+
args_schema=tool["args_schema"],
|
|
94
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
93
95
|
))
|
|
94
96
|
return cls(tools=tools)
|
|
95
97
|
|
alita_sdk/tools/base/tool.py
CHANGED
|
@@ -23,6 +23,10 @@ class BaseAction(BaseTool):
|
|
|
23
23
|
) -> ToolException | str:
|
|
24
24
|
"""Use the Confluence API to run an operation."""
|
|
25
25
|
try:
|
|
26
|
-
|
|
26
|
+
# Strip numeric suffix added for deduplication (_2, _3, etc.)
|
|
27
|
+
# to get the original tool name that exists in the wrapper
|
|
28
|
+
import re
|
|
29
|
+
tool_name = re.sub(r'_\d+$', '', self.name)
|
|
30
|
+
return self.api_wrapper.run(tool_name, *args, **kwargs)
|
|
27
31
|
except Exception as e:
|
|
28
32
|
return ToolException(f"An exception occurred: {e}")
|
|
@@ -386,7 +386,8 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
386
386
|
|
|
387
387
|
def remove_index(self, index_name: str = ""):
|
|
388
388
|
"""Cleans the indexed data in the collection."""
|
|
389
|
-
super()._clean_collection(index_name=index_name)
|
|
389
|
+
super()._clean_collection(index_name=index_name, including_index_meta=True)
|
|
390
|
+
self._emit_index_data_removed_event(index_name)
|
|
390
391
|
return (f"Collection '{index_name}' has been removed from the vector store.\n"
|
|
391
392
|
f"Available collections: {self.list_collections()}") if index_name \
|
|
392
393
|
else "All collections have been removed from the vector store."
|
|
@@ -641,6 +642,30 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
641
642
|
except Exception as e:
|
|
642
643
|
logger.warning(f"Failed to emit index_data_status event: {e}")
|
|
643
644
|
|
|
645
|
+
def _emit_index_data_removed_event(self, index_name: str):
|
|
646
|
+
"""
|
|
647
|
+
Emit custom event for index data removing.
|
|
648
|
+
|
|
649
|
+
Args:
|
|
650
|
+
index_name: The name of the index
|
|
651
|
+
toolkit_id: The toolkit identifier
|
|
652
|
+
"""
|
|
653
|
+
# Build event message
|
|
654
|
+
event_data = {
|
|
655
|
+
"index_name": index_name,
|
|
656
|
+
"toolkit_id": self.toolkit_id,
|
|
657
|
+
"project_id": self.alita.project_id,
|
|
658
|
+
}
|
|
659
|
+
# Emit the event
|
|
660
|
+
try:
|
|
661
|
+
dispatch_custom_event("index_data_removed", event_data)
|
|
662
|
+
logger.debug(
|
|
663
|
+
f"Emitted index_data_removed event for index "
|
|
664
|
+
f"'{index_name}': {event_data}"
|
|
665
|
+
)
|
|
666
|
+
except Exception as e:
|
|
667
|
+
logger.warning(f"Failed to emit index_data_removed event: {e}")
|
|
668
|
+
|
|
644
669
|
def get_available_tools(self):
|
|
645
670
|
"""
|
|
646
671
|
Returns the standardized vector search tools (search operations only).
|
|
@@ -9,7 +9,7 @@ from pydantic import BaseModel, Field, ConfigDict, create_model
|
|
|
9
9
|
|
|
10
10
|
from ..base.tool import BaseAction
|
|
11
11
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
12
|
-
from ..utils import clean_string,
|
|
12
|
+
from ..utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
13
13
|
from ...configurations.bitbucket import BitbucketConfiguration
|
|
14
14
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
15
15
|
import requests
|
|
@@ -18,7 +18,7 @@ import requests
|
|
|
18
18
|
name = "bitbucket"
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def
|
|
21
|
+
def get_toolkit(tool):
|
|
22
22
|
return AlitaBitbucketToolkit.get_toolkit(
|
|
23
23
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
24
24
|
project=tool['settings']['project'],
|
|
@@ -33,18 +33,19 @@ def get_tools(tool):
|
|
|
33
33
|
doctype='code',
|
|
34
34
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
35
35
|
toolkit_name=tool.get('toolkit_name')
|
|
36
|
-
)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def get_tools(tool):
|
|
39
|
+
return get_toolkit(tool).get_tools()
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
class AlitaBitbucketToolkit(BaseToolkit):
|
|
40
43
|
tools: List[BaseTool] = []
|
|
41
|
-
toolkit_max_length: int = 0
|
|
42
44
|
|
|
43
45
|
@staticmethod
|
|
44
46
|
def toolkit_config_schema() -> BaseModel:
|
|
45
47
|
selected_tools = {x['name']: x['args_schema'].schema() for x in
|
|
46
48
|
BitbucketAPIWrapper.model_construct().get_available_tools()}
|
|
47
|
-
AlitaBitbucketToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
48
49
|
m = create_model(
|
|
49
50
|
name,
|
|
50
51
|
project=(str, Field(description="Project/Workspace")),
|
|
@@ -61,7 +62,6 @@ class AlitaBitbucketToolkit(BaseToolkit):
|
|
|
61
62
|
'metadata':
|
|
62
63
|
{
|
|
63
64
|
"label": "Bitbucket", "icon_url": "bitbucket-icon.svg",
|
|
64
|
-
"max_length": AlitaBitbucketToolkit.toolkit_max_length,
|
|
65
65
|
"categories": ["code repositories"],
|
|
66
66
|
"extra_categories": ["bitbucket", "git", "repository", "code", "version control"],
|
|
67
67
|
}
|
|
@@ -100,17 +100,21 @@ class AlitaBitbucketToolkit(BaseToolkit):
|
|
|
100
100
|
}
|
|
101
101
|
bitbucket_api_wrapper = BitbucketAPIWrapper(**wrapper_payload)
|
|
102
102
|
available_tools: List[Dict] = bitbucket_api_wrapper.get_available_tools()
|
|
103
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
104
103
|
tools = []
|
|
105
104
|
for tool in available_tools:
|
|
106
105
|
if selected_tools:
|
|
107
106
|
if tool['name'] not in selected_tools:
|
|
108
107
|
continue
|
|
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]
|
|
109
112
|
tools.append(BaseAction(
|
|
110
113
|
api_wrapper=bitbucket_api_wrapper,
|
|
111
|
-
name=
|
|
112
|
-
description=
|
|
113
|
-
args_schema=tool["args_schema"]
|
|
114
|
+
name=tool["name"],
|
|
115
|
+
description=description,
|
|
116
|
+
args_schema=tool["args_schema"],
|
|
117
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
114
118
|
))
|
|
115
119
|
return cls(tools=tools)
|
|
116
120
|
|
|
@@ -13,6 +13,7 @@ from pydantic.fields import PrivateAttr
|
|
|
13
13
|
|
|
14
14
|
from ..code_indexer_toolkit import CodeIndexerToolkit
|
|
15
15
|
from ..utils.available_tools_decorator import extend_with_parent_available_tools
|
|
16
|
+
from ..elitea_base import extend_with_file_operations, BaseCodeToolApiWrapper
|
|
16
17
|
|
|
17
18
|
logger = logging.getLogger(__name__)
|
|
18
19
|
|
|
@@ -123,6 +124,12 @@ class BitbucketAPIWrapper(CodeIndexerToolkit):
|
|
|
123
124
|
|
|
124
125
|
_bitbucket: Any = PrivateAttr()
|
|
125
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
|
|
126
133
|
url: str = ''
|
|
127
134
|
project: str = ''
|
|
128
135
|
"""The key of the project this repo belongs to"""
|
|
@@ -360,12 +367,15 @@ class BitbucketAPIWrapper(CodeIndexerToolkit):
|
|
|
360
367
|
# except Exception as e:
|
|
361
368
|
# raise ToolException(f"Can't extract file commit hash (`{file_path}`) due to error:\n{str(e)}")
|
|
362
369
|
|
|
363
|
-
def _read_file(self, file_path: str, branch: str) -> str:
|
|
370
|
+
def _read_file(self, file_path: str, branch: str, **kwargs) -> str:
|
|
364
371
|
"""
|
|
365
|
-
Reads a file from the
|
|
372
|
+
Reads a file from the bitbucket repo with optional partial read support.
|
|
373
|
+
|
|
366
374
|
Parameters:
|
|
367
375
|
file_path(str): the file path
|
|
368
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
|
|
369
379
|
Returns:
|
|
370
380
|
str: The file decoded as a string
|
|
371
381
|
"""
|
|
@@ -399,8 +409,46 @@ class BitbucketAPIWrapper(CodeIndexerToolkit):
|
|
|
399
409
|
return self._read_file(file_path, branch)
|
|
400
410
|
except Exception as e:
|
|
401
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)}")
|
|
402
449
|
|
|
403
450
|
@extend_with_parent_available_tools
|
|
451
|
+
@extend_with_file_operations
|
|
404
452
|
def get_available_tools(self):
|
|
405
453
|
return [
|
|
406
454
|
{
|
|
@@ -8,7 +8,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
|
|
11
|
+
from ..utils import get_max_toolkit_length, clean_string
|
|
12
12
|
from ...configurations.browser import BrowserConfiguration
|
|
13
13
|
from logging import getLogger
|
|
14
14
|
|
|
@@ -42,7 +42,6 @@ class BrowserToolkit(BaseToolkit):
|
|
|
42
42
|
'google': GoogleSearchResults.__pydantic_fields__['args_schema'].default.schema(),
|
|
43
43
|
'wiki': WikipediaQueryRun.__pydantic_fields__['args_schema'].default.schema()
|
|
44
44
|
}
|
|
45
|
-
BrowserToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
46
45
|
|
|
47
46
|
def validate_google_fields(cls, values):
|
|
48
47
|
if 'google' in values.get('selected_tools', []):
|
|
@@ -90,7 +89,6 @@ class BrowserToolkit(BaseToolkit):
|
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
tools = []
|
|
93
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
94
92
|
if not selected_tools:
|
|
95
93
|
selected_tools = [
|
|
96
94
|
'single_url_crawler',
|
|
@@ -127,7 +125,10 @@ class BrowserToolkit(BaseToolkit):
|
|
|
127
125
|
|
|
128
126
|
# Only add the tool if it was successfully created
|
|
129
127
|
if tool_entry is not None:
|
|
130
|
-
|
|
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}
|
|
131
132
|
tools.append(tool_entry)
|
|
132
133
|
return cls(tools=tools)
|
|
133
134
|
|
|
@@ -7,7 +7,7 @@ from functools import lru_cache
|
|
|
7
7
|
from .api_wrapper import CarrierAPIWrapper
|
|
8
8
|
from .tools import __all__
|
|
9
9
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
-
from ..utils import clean_string,
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
11
11
|
from ...configurations.carrier import CarrierConfiguration
|
|
12
12
|
|
|
13
13
|
logger = logging.getLogger(__name__)
|
|
@@ -17,7 +17,6 @@ name = 'carrier'
|
|
|
17
17
|
|
|
18
18
|
class AlitaCarrierToolkit(BaseToolkit):
|
|
19
19
|
tools: List[BaseTool] = []
|
|
20
|
-
toolkit_max_length: int = 100
|
|
21
20
|
|
|
22
21
|
@classmethod
|
|
23
22
|
@lru_cache(maxsize=32)
|
|
@@ -26,7 +25,6 @@ class AlitaCarrierToolkit(BaseToolkit):
|
|
|
26
25
|
for t in __all__:
|
|
27
26
|
default = t['tool'].__pydantic_fields__['args_schema'].default
|
|
28
27
|
selected_tools[t['name']] = default.schema() if default else default
|
|
29
|
-
cls.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
30
28
|
return create_model(
|
|
31
29
|
name,
|
|
32
30
|
project_id=(Optional[str], Field(None, description="Optional project ID for scoped operations")),
|
|
@@ -70,15 +68,16 @@ class AlitaCarrierToolkit(BaseToolkit):
|
|
|
70
68
|
logger.exception(f"[AlitaCarrierToolkit] Error initializing CarrierAPIWrapper: {e}")
|
|
71
69
|
raise ValueError(f"CarrierAPIWrapper initialization error: {e}")
|
|
72
70
|
|
|
73
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
74
|
-
|
|
75
71
|
tools = []
|
|
76
72
|
for tool_def in __all__:
|
|
77
73
|
if selected_tools and tool_def['name'] not in selected_tools:
|
|
78
74
|
continue
|
|
79
75
|
try:
|
|
80
76
|
tool_instance = tool_def['tool'](api_wrapper=carrier_api_wrapper)
|
|
81
|
-
|
|
77
|
+
if toolkit_name:
|
|
78
|
+
tool_instance.description = f"{tool_instance.description}\nToolkit: {toolkit_name}"
|
|
79
|
+
tool_instance.description = tool_instance.description[:1000]
|
|
80
|
+
tool_instance.metadata = {"toolkit_name": toolkit_name}
|
|
82
81
|
tools.append(tool_instance)
|
|
83
82
|
logger.info(f"[AlitaCarrierToolkit] Successfully initialized tool '{tool_instance.name}'")
|
|
84
83
|
except Exception as e:
|
|
@@ -17,6 +17,7 @@ def json_chunker(file_content_generator: Generator[Document, None, None], config
|
|
|
17
17
|
for chunk in chunks:
|
|
18
18
|
metadata = doc.metadata.copy()
|
|
19
19
|
metadata['chunk_id'] = chunk_id
|
|
20
|
+
metadata['method_name'] = 'json'
|
|
20
21
|
chunk_id += 1
|
|
21
22
|
yield Document(page_content=json.dumps(chunk), metadata=metadata)
|
|
22
23
|
except Exception as e:
|
|
@@ -60,6 +60,7 @@ def markdown_chunker(file_content_generator: Generator[Document, None, None], co
|
|
|
60
60
|
docmeta.update({"headers": "; ".join(headers_meta)})
|
|
61
61
|
docmeta['chunk_id'] = chunk_id
|
|
62
62
|
docmeta['chunk_type'] = "document"
|
|
63
|
+
docmeta['method_name'] = 'markdown'
|
|
63
64
|
yield Document(
|
|
64
65
|
page_content=subchunk,
|
|
65
66
|
metadata=docmeta
|
|
@@ -71,6 +72,7 @@ def markdown_chunker(file_content_generator: Generator[Document, None, None], co
|
|
|
71
72
|
docmeta.update({"headers": "; ".join(headers_meta)})
|
|
72
73
|
docmeta['chunk_id'] = chunk_id
|
|
73
74
|
docmeta['chunk_type'] = "document"
|
|
75
|
+
docmeta['method_name'] = 'text'
|
|
74
76
|
yield Document(
|
|
75
77
|
page_content=chunk.page_content,
|
|
76
78
|
metadata=docmeta
|
|
@@ -6,7 +6,7 @@ from langchain_core.tools import BaseToolkit, BaseTool
|
|
|
6
6
|
from .api_wrapper import AWSToolConfig
|
|
7
7
|
from ...base.tool import BaseAction
|
|
8
8
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ...utils import clean_string,
|
|
9
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
10
10
|
|
|
11
11
|
name = "aws"
|
|
12
12
|
|
|
@@ -22,12 +22,10 @@ def get_tools(tool):
|
|
|
22
22
|
|
|
23
23
|
class AWSToolkit(BaseToolkit):
|
|
24
24
|
tools: list[BaseTool] = []
|
|
25
|
-
toolkit_max_length: int = 0
|
|
26
25
|
|
|
27
26
|
@staticmethod
|
|
28
27
|
def toolkit_config_schema() -> BaseModel:
|
|
29
28
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AWSToolConfig.model_construct().get_available_tools()}
|
|
30
|
-
AWSToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
31
29
|
return create_model(
|
|
32
30
|
name,
|
|
33
31
|
region=(str, Field(default="", title="Region", description="AWS region")),
|
|
@@ -54,15 +52,19 @@ class AWSToolkit(BaseToolkit):
|
|
|
54
52
|
aws_tool_config = AWSToolConfig(**kwargs)
|
|
55
53
|
available_tools = aws_tool_config.get_available_tools()
|
|
56
54
|
tools = []
|
|
57
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
58
55
|
for tool in available_tools:
|
|
59
56
|
if selected_tools and tool["name"] not in selected_tools:
|
|
60
57
|
continue
|
|
58
|
+
description = tool["description"]
|
|
59
|
+
if toolkit_name:
|
|
60
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
61
|
+
description = description[:1000]
|
|
61
62
|
tools.append(BaseAction(
|
|
62
63
|
api_wrapper=aws_tool_config,
|
|
63
|
-
name=
|
|
64
|
-
description=
|
|
65
|
-
args_schema=tool["args_schema"]
|
|
64
|
+
name=tool["name"],
|
|
65
|
+
description=description,
|
|
66
|
+
args_schema=tool["args_schema"],
|
|
67
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
66
68
|
))
|
|
67
69
|
return cls(tools=tools)
|
|
68
70
|
|
|
@@ -6,7 +6,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, SecretStr
|
|
|
6
6
|
from .api_wrapper import AzureApiWrapper
|
|
7
7
|
from ...base.tool import BaseAction
|
|
8
8
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ...utils import clean_string,
|
|
9
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
10
10
|
|
|
11
11
|
name = "azure"
|
|
12
12
|
|
|
@@ -23,12 +23,10 @@ def get_tools(tool):
|
|
|
23
23
|
|
|
24
24
|
class AzureToolkit(BaseToolkit):
|
|
25
25
|
tools: list[BaseTool] = []
|
|
26
|
-
toolkit_max_length: int = 0
|
|
27
26
|
|
|
28
27
|
@staticmethod
|
|
29
28
|
def toolkit_config_schema() -> BaseModel:
|
|
30
29
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AzureApiWrapper.model_construct().get_available_tools()}
|
|
31
|
-
AzureToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
32
30
|
return create_model(
|
|
33
31
|
name,
|
|
34
32
|
subscription_id=(str, Field(default="", title="Subscription ID", description="Azure subscription ID")),
|
|
@@ -47,15 +45,19 @@ class AzureToolkit(BaseToolkit):
|
|
|
47
45
|
azure_api_wrapper = AzureApiWrapper(**kwargs)
|
|
48
46
|
available_tools = azure_api_wrapper.get_available_tools()
|
|
49
47
|
tools = []
|
|
50
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
51
48
|
for tool in available_tools:
|
|
52
49
|
if selected_tools and tool["name"] not in selected_tools:
|
|
53
50
|
continue
|
|
51
|
+
description = tool["description"]
|
|
52
|
+
if toolkit_name:
|
|
53
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
54
|
+
description = description[:1000]
|
|
54
55
|
tools.append(BaseAction(
|
|
55
56
|
api_wrapper=azure_api_wrapper,
|
|
56
|
-
name=
|
|
57
|
-
description=
|
|
58
|
-
args_schema=tool["args_schema"]
|
|
57
|
+
name=tool["name"],
|
|
58
|
+
description=description,
|
|
59
|
+
args_schema=tool["args_schema"],
|
|
60
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
59
61
|
))
|
|
60
62
|
return cls(tools=tools)
|
|
61
63
|
|
|
@@ -6,7 +6,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, SecretStr
|
|
|
6
6
|
from .api_wrapper import GCPApiWrapper
|
|
7
7
|
from ...base.tool import BaseAction
|
|
8
8
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ...utils import clean_string,
|
|
9
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
10
10
|
|
|
11
11
|
name = "gcp"
|
|
12
12
|
|
|
@@ -20,12 +20,10 @@ def get_tools(tool):
|
|
|
20
20
|
|
|
21
21
|
class GCPToolkit(BaseToolkit):
|
|
22
22
|
tools: list[BaseTool] = []
|
|
23
|
-
toolkit_max_length: int = 0
|
|
24
23
|
|
|
25
24
|
@staticmethod
|
|
26
25
|
def toolkit_config_schema() -> BaseModel:
|
|
27
26
|
selected_tools = {x['name']: x['args_schema'].schema() for x in GCPApiWrapper.model_construct().get_available_tools()}
|
|
28
|
-
GCPToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
29
27
|
return create_model(
|
|
30
28
|
name,
|
|
31
29
|
api_key=(SecretStr, Field(default="", title="API key", description="GCP API key", json_schema_extra={'secret': True})),
|
|
@@ -41,15 +39,19 @@ class GCPToolkit(BaseToolkit):
|
|
|
41
39
|
gcp_api_wrapper = GCPApiWrapper(**kwargs)
|
|
42
40
|
available_tools = gcp_api_wrapper.get_available_tools()
|
|
43
41
|
tools = []
|
|
44
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
45
42
|
for tool in available_tools:
|
|
46
43
|
if selected_tools and tool["name"] not in selected_tools:
|
|
47
44
|
continue
|
|
45
|
+
description = tool["description"]
|
|
46
|
+
if toolkit_name:
|
|
47
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
48
|
+
description = description[:1000]
|
|
48
49
|
tools.append(BaseAction(
|
|
49
50
|
api_wrapper=gcp_api_wrapper,
|
|
50
|
-
name=
|
|
51
|
-
description=
|
|
52
|
-
args_schema=tool["args_schema"]
|
|
51
|
+
name=tool["name"],
|
|
52
|
+
description=description,
|
|
53
|
+
args_schema=tool["args_schema"],
|
|
54
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
53
55
|
))
|
|
54
56
|
return cls(tools=tools)
|
|
55
57
|
|