alita-sdk 0.3.462__py3-none-any.whl → 0.3.627__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +15 -3
- alita_sdk/cli/agent_loader.py +56 -8
- alita_sdk/cli/agent_ui.py +93 -31
- alita_sdk/cli/agents.py +2274 -230
- alita_sdk/cli/callbacks.py +96 -25
- alita_sdk/cli/cli.py +10 -1
- alita_sdk/cli/config.py +162 -9
- alita_sdk/cli/context/__init__.py +30 -0
- alita_sdk/cli/context/cleanup.py +198 -0
- alita_sdk/cli/context/manager.py +731 -0
- alita_sdk/cli/context/message.py +285 -0
- alita_sdk/cli/context/strategies.py +289 -0
- alita_sdk/cli/context/token_estimation.py +127 -0
- alita_sdk/cli/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1073 -0
- alita_sdk/cli/testcases/__init__.py +94 -0
- alita_sdk/cli/testcases/data_generation.py +119 -0
- alita_sdk/cli/testcases/discovery.py +96 -0
- alita_sdk/cli/testcases/executor.py +84 -0
- alita_sdk/cli/testcases/logger.py +85 -0
- alita_sdk/cli/testcases/parser.py +172 -0
- alita_sdk/cli/testcases/prompts.py +91 -0
- alita_sdk/cli/testcases/reporting.py +125 -0
- alita_sdk/cli/testcases/setup.py +108 -0
- alita_sdk/cli/testcases/test_runner.py +282 -0
- alita_sdk/cli/testcases/utils.py +39 -0
- alita_sdk/cli/testcases/validation.py +90 -0
- alita_sdk/cli/testcases/workflow.py +196 -0
- alita_sdk/cli/toolkit.py +14 -17
- alita_sdk/cli/toolkit_loader.py +35 -5
- alita_sdk/cli/tools/__init__.py +36 -2
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +910 -64
- alita_sdk/cli/tools/planning.py +389 -0
- alita_sdk/cli/tools/terminal.py +414 -0
- alita_sdk/community/__init__.py +72 -12
- alita_sdk/community/inventory/__init__.py +236 -0
- alita_sdk/community/inventory/config.py +257 -0
- alita_sdk/community/inventory/enrichment.py +2137 -0
- alita_sdk/community/inventory/extractors.py +1469 -0
- alita_sdk/community/inventory/ingestion.py +3172 -0
- alita_sdk/community/inventory/knowledge_graph.py +1457 -0
- alita_sdk/community/inventory/parsers/__init__.py +218 -0
- alita_sdk/community/inventory/parsers/base.py +295 -0
- alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
- alita_sdk/community/inventory/parsers/go_parser.py +851 -0
- alita_sdk/community/inventory/parsers/html_parser.py +389 -0
- alita_sdk/community/inventory/parsers/java_parser.py +593 -0
- alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
- alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
- alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
- alita_sdk/community/inventory/parsers/python_parser.py +604 -0
- alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
- alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
- alita_sdk/community/inventory/parsers/text_parser.py +322 -0
- alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
- alita_sdk/community/inventory/patterns/__init__.py +61 -0
- alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
- alita_sdk/community/inventory/patterns/loader.py +348 -0
- alita_sdk/community/inventory/patterns/registry.py +198 -0
- alita_sdk/community/inventory/presets.py +535 -0
- alita_sdk/community/inventory/retrieval.py +1403 -0
- alita_sdk/community/inventory/toolkit.py +173 -0
- alita_sdk/community/inventory/toolkit_utils.py +176 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/__init__.py +1 -1
- alita_sdk/configurations/ado.py +141 -20
- alita_sdk/configurations/bitbucket.py +0 -3
- alita_sdk/configurations/confluence.py +76 -42
- alita_sdk/configurations/figma.py +76 -0
- alita_sdk/configurations/gitlab.py +17 -5
- alita_sdk/configurations/openapi.py +329 -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 +3 -3
- alita_sdk/runtime/clients/client.py +353 -48
- alita_sdk/runtime/clients/sandbox_client.py +0 -21
- alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
- alita_sdk/runtime/langchain/assistant.py +123 -26
- alita_sdk/runtime/langchain/constants.py +642 -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 +6 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +226 -7
- alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +5 -2
- alita_sdk/runtime/langchain/document_loaders/constants.py +12 -7
- alita_sdk/runtime/langchain/langraph_agent.py +279 -73
- alita_sdk/runtime/langchain/utils.py +82 -15
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/skills/__init__.py +91 -0
- alita_sdk/runtime/skills/callbacks.py +498 -0
- alita_sdk/runtime/skills/discovery.py +540 -0
- alita_sdk/runtime/skills/executor.py +610 -0
- alita_sdk/runtime/skills/input_builder.py +371 -0
- alita_sdk/runtime/skills/models.py +330 -0
- alita_sdk/runtime/skills/registry.py +355 -0
- alita_sdk/runtime/skills/skill_runner.py +330 -0
- alita_sdk/runtime/toolkits/__init__.py +7 -0
- alita_sdk/runtime/toolkits/application.py +21 -9
- alita_sdk/runtime/toolkits/artifact.py +15 -5
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +139 -251
- alita_sdk/runtime/toolkits/mcp_config.py +1048 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/skill_router.py +238 -0
- alita_sdk/runtime/toolkits/subgraph.py +251 -6
- alita_sdk/runtime/toolkits/tools.py +238 -32
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/__init__.py +3 -1
- alita_sdk/runtime/tools/application.py +20 -6
- alita_sdk/runtime/tools/artifact.py +511 -28
- alita_sdk/runtime/tools/data_analysis.py +183 -0
- alita_sdk/runtime/tools/function.py +43 -15
- alita_sdk/runtime/tools/image_generation.py +50 -44
- alita_sdk/runtime/tools/llm.py +852 -67
- alita_sdk/runtime/tools/loop.py +3 -1
- alita_sdk/runtime/tools/loop_output.py +3 -1
- alita_sdk/runtime/tools/mcp_remote_tool.py +25 -10
- alita_sdk/runtime/tools/mcp_server_tool.py +7 -6
- alita_sdk/runtime/tools/planning/__init__.py +36 -0
- alita_sdk/runtime/tools/planning/models.py +246 -0
- alita_sdk/runtime/tools/planning/wrapper.py +607 -0
- alita_sdk/runtime/tools/router.py +2 -4
- alita_sdk/runtime/tools/sandbox.py +9 -6
- alita_sdk/runtime/tools/skill_router.py +776 -0
- alita_sdk/runtime/tools/tool.py +3 -1
- alita_sdk/runtime/tools/vectorstore.py +7 -2
- alita_sdk/runtime/tools/vectorstore_base.py +51 -11
- alita_sdk/runtime/utils/AlitaCallback.py +137 -21
- alita_sdk/runtime/utils/constants.py +5 -1
- alita_sdk/runtime/utils/mcp_client.py +492 -0
- alita_sdk/runtime/utils/mcp_oauth.py +202 -5
- alita_sdk/runtime/utils/mcp_sse_client.py +36 -7
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/serialization.py +155 -0
- alita_sdk/runtime/utils/streamlit.py +6 -10
- alita_sdk/runtime/utils/toolkit_utils.py +16 -5
- alita_sdk/runtime/utils/utils.py +36 -0
- alita_sdk/tools/__init__.py +113 -29
- alita_sdk/tools/ado/repos/__init__.py +51 -33
- alita_sdk/tools/ado/repos/repos_wrapper.py +148 -89
- alita_sdk/tools/ado/test_plan/__init__.py +25 -9
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +23 -1
- alita_sdk/tools/ado/utils.py +1 -18
- alita_sdk/tools/ado/wiki/__init__.py +25 -8
- alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
- alita_sdk/tools/ado/work_item/__init__.py +26 -9
- alita_sdk/tools/ado/work_item/ado_wrapper.py +56 -3
- alita_sdk/tools/advanced_jira_mining/__init__.py +11 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +13 -9
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +11 -8
- alita_sdk/tools/azure_ai/search/api_wrapper.py +1 -1
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +170 -45
- alita_sdk/tools/bitbucket/__init__.py +17 -12
- alita_sdk/tools/bitbucket/api_wrapper.py +59 -11
- alita_sdk/tools/bitbucket/cloud_api_wrapper.py +49 -35
- alita_sdk/tools/browser/__init__.py +5 -4
- alita_sdk/tools/carrier/__init__.py +5 -6
- alita_sdk/tools/carrier/backend_reports_tool.py +6 -6
- alita_sdk/tools/carrier/run_ui_test_tool.py +6 -6
- alita_sdk/tools/carrier/ui_reports_tool.py +5 -5
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/code/treesitter/treesitter.py +37 -13
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +10 -7
- alita_sdk/tools/cloud/azure/__init__.py +10 -7
- alita_sdk/tools/cloud/gcp/__init__.py +10 -7
- alita_sdk/tools/cloud/k8s/__init__.py +10 -7
- alita_sdk/tools/code/linter/__init__.py +10 -8
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +10 -7
- alita_sdk/tools/code_indexer_toolkit.py +73 -23
- alita_sdk/tools/confluence/__init__.py +21 -15
- alita_sdk/tools/confluence/api_wrapper.py +78 -23
- alita_sdk/tools/confluence/loader.py +4 -2
- alita_sdk/tools/custom_open_api/__init__.py +12 -5
- alita_sdk/tools/elastic/__init__.py +11 -8
- alita_sdk/tools/elitea_base.py +493 -30
- alita_sdk/tools/figma/__init__.py +58 -11
- alita_sdk/tools/figma/api_wrapper.py +1235 -143
- alita_sdk/tools/figma/figma_client.py +73 -0
- alita_sdk/tools/figma/toon_tools.py +2748 -0
- alita_sdk/tools/github/__init__.py +13 -14
- alita_sdk/tools/github/github_client.py +224 -100
- alita_sdk/tools/github/graphql_client_wrapper.py +119 -33
- alita_sdk/tools/github/schemas.py +14 -5
- alita_sdk/tools/github/tool.py +5 -1
- alita_sdk/tools/github/tool_prompts.py +9 -22
- alita_sdk/tools/gitlab/__init__.py +15 -11
- alita_sdk/tools/gitlab/api_wrapper.py +207 -41
- alita_sdk/tools/gitlab_org/__init__.py +10 -8
- alita_sdk/tools/gitlab_org/api_wrapper.py +63 -64
- alita_sdk/tools/google/bigquery/__init__.py +13 -12
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +10 -8
- alita_sdk/tools/google_places/api_wrapper.py +1 -1
- alita_sdk/tools/jira/__init__.py +17 -11
- alita_sdk/tools/jira/api_wrapper.py +91 -40
- alita_sdk/tools/keycloak/__init__.py +11 -8
- alita_sdk/tools/localgit/__init__.py +9 -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/non_code_indexer_toolkit.py +1 -0
- alita_sdk/tools/ocr/__init__.py +11 -8
- alita_sdk/tools/openapi/__init__.py +490 -114
- alita_sdk/tools/openapi/api_wrapper.py +1368 -0
- alita_sdk/tools/openapi/tool.py +20 -0
- alita_sdk/tools/pandas/__init__.py +20 -12
- alita_sdk/tools/pandas/api_wrapper.py +38 -25
- alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
- alita_sdk/tools/postman/__init__.py +11 -11
- alita_sdk/tools/pptx/__init__.py +10 -9
- alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
- alita_sdk/tools/qtest/__init__.py +30 -10
- alita_sdk/tools/qtest/api_wrapper.py +430 -13
- alita_sdk/tools/rally/__init__.py +10 -8
- alita_sdk/tools/rally/api_wrapper.py +1 -1
- alita_sdk/tools/report_portal/__init__.py +12 -9
- alita_sdk/tools/salesforce/__init__.py +10 -9
- alita_sdk/tools/servicenow/__init__.py +17 -14
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +10 -8
- alita_sdk/tools/sharepoint/api_wrapper.py +4 -4
- alita_sdk/tools/slack/__init__.py +10 -8
- alita_sdk/tools/slack/api_wrapper.py +2 -2
- alita_sdk/tools/sql/__init__.py +11 -9
- alita_sdk/tools/testio/__init__.py +10 -8
- alita_sdk/tools/testrail/__init__.py +11 -8
- alita_sdk/tools/testrail/api_wrapper.py +1 -1
- alita_sdk/tools/utils/__init__.py +9 -4
- alita_sdk/tools/utils/content_parser.py +77 -3
- alita_sdk/tools/utils/text_operations.py +410 -0
- alita_sdk/tools/utils/tool_prompts.py +79 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +17 -13
- alita_sdk/tools/xray/__init__.py +12 -9
- alita_sdk/tools/yagmail/__init__.py +9 -3
- alita_sdk/tools/zephyr/__init__.py +9 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +11 -8
- alita_sdk/tools/zephyr_essential/__init__.py +10 -8
- alita_sdk/tools/zephyr_essential/api_wrapper.py +30 -13
- alita_sdk/tools/zephyr_essential/client.py +2 -2
- alita_sdk/tools/zephyr_scale/__init__.py +11 -9
- alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
- alita_sdk/tools/zephyr_squad/__init__.py +10 -8
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +147 -7
- alita_sdk-0.3.627.dist-info/RECORD +468 -0
- alita_sdk-0.3.627.dist-info/entry_points.txt +2 -0
- alita_sdk-0.3.462.dist-info/RECORD +0 -384
- alita_sdk-0.3.462.dist-info/entry_points.txt +0 -2
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
|
@@ -6,9 +6,10 @@ 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
|
+
from ....runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
12
13
|
|
|
13
14
|
name = "delta_lake"
|
|
14
15
|
|
|
@@ -21,10 +22,6 @@ def get_available_tools() -> dict[str, dict]:
|
|
|
21
22
|
}
|
|
22
23
|
return available_tools
|
|
23
24
|
|
|
24
|
-
toolkit_max_length = lru_cache(maxsize=1)(
|
|
25
|
-
lambda: get_max_toolkit_length(get_available_tools())
|
|
26
|
-
)
|
|
27
|
-
|
|
28
25
|
class DeltaLakeToolkitConfig(BaseModel):
|
|
29
26
|
class Config:
|
|
30
27
|
title = name
|
|
@@ -87,9 +84,10 @@ class DeltaLakeToolkit(BaseToolkit):
|
|
|
87
84
|
|
|
88
85
|
@computed_field
|
|
89
86
|
@property
|
|
90
|
-
def
|
|
87
|
+
def toolkit_context(self) -> str:
|
|
88
|
+
"""Returns toolkit context for descriptions (max 1000 chars)."""
|
|
91
89
|
return (
|
|
92
|
-
clean_string(self.toolkit_name,
|
|
90
|
+
f" [Toolkit: {clean_string(self.toolkit_name, 0)}]"
|
|
93
91
|
if self.toolkit_name
|
|
94
92
|
else ""
|
|
95
93
|
)
|
|
@@ -118,12 +116,18 @@ class DeltaLakeToolkit(BaseToolkit):
|
|
|
118
116
|
selected_tools = set(selected_tools)
|
|
119
117
|
for t in instance.available_tools:
|
|
120
118
|
if t["name"] in selected_tools:
|
|
119
|
+
description = t["description"]
|
|
120
|
+
if toolkit_name:
|
|
121
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
122
|
+
description = f"S3 Path: {getattr(instance.api_wrapper, 's3_path', '')} Table Path: {getattr(instance.api_wrapper, 'table_path', '')}\n{description}"
|
|
123
|
+
description = description[:1000]
|
|
121
124
|
instance.tools.append(
|
|
122
125
|
DeltaLakeAction(
|
|
123
126
|
api_wrapper=instance.api_wrapper,
|
|
124
|
-
name=
|
|
125
|
-
description=
|
|
127
|
+
name=t["name"],
|
|
128
|
+
description=description,
|
|
126
129
|
args_schema=t["args_schema"],
|
|
130
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: t["name"]} if toolkit_name else {TOOL_NAME_META: t["name"]}
|
|
127
131
|
)
|
|
128
132
|
)
|
|
129
133
|
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,9 +6,10 @@ 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
|
+
from ....runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
12
13
|
|
|
13
14
|
logger = getLogger(__name__)
|
|
14
15
|
|
|
@@ -31,12 +32,10 @@ def get_toolkit():
|
|
|
31
32
|
|
|
32
33
|
class AzureSearchToolkit(BaseToolkit):
|
|
33
34
|
tools: List[BaseTool] = []
|
|
34
|
-
toolkit_max_length: int = 0
|
|
35
35
|
|
|
36
36
|
@staticmethod
|
|
37
37
|
def toolkit_config_schema() -> BaseModel:
|
|
38
38
|
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
39
|
m = create_model(
|
|
41
40
|
name,
|
|
42
41
|
index_name=(str, Field(description="Azure Search index name")),
|
|
@@ -46,7 +45,7 @@ class AzureSearchToolkit(BaseToolkit):
|
|
|
46
45
|
),
|
|
47
46
|
api_version=(Optional[str], Field(description="API version", default=None)),
|
|
48
47
|
openai_api_key=(Optional[str], Field(description="Azure OpenAI API Key", default=None, json_schema_extra={'secret': True})),
|
|
49
|
-
model_name=(str, Field(description="Model name for Embeddings model", default=None)),
|
|
48
|
+
model_name=(Optional[str], Field(description="Model name for Embeddings model", default=None)),
|
|
50
49
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
51
50
|
__config__=ConfigDict(json_schema_extra={
|
|
52
51
|
'metadata': {
|
|
@@ -79,17 +78,21 @@ class AzureSearchToolkit(BaseToolkit):
|
|
|
79
78
|
}
|
|
80
79
|
azure_search_api_wrapper = AzureSearchApiWrapper(**wrapper_payload)
|
|
81
80
|
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
81
|
tools = []
|
|
84
82
|
for tool in available_tools:
|
|
85
83
|
if selected_tools:
|
|
86
84
|
if tool["name"] not in selected_tools:
|
|
87
85
|
continue
|
|
86
|
+
description = tool["description"]
|
|
87
|
+
if toolkit_name:
|
|
88
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
89
|
+
description = description[:1000]
|
|
88
90
|
tools.append(BaseAction(
|
|
89
91
|
api_wrapper=azure_search_api_wrapper,
|
|
90
|
-
name=
|
|
91
|
-
description=
|
|
92
|
-
args_schema=tool["args_schema"]
|
|
92
|
+
name=tool["name"],
|
|
93
|
+
description=description,
|
|
94
|
+
args_schema=tool["args_schema"],
|
|
95
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
93
96
|
))
|
|
94
97
|
return cls(tools=tools)
|
|
95
98
|
|
|
@@ -11,7 +11,7 @@ logger = logging.getLogger(__name__)
|
|
|
11
11
|
|
|
12
12
|
class AzureSearchInput(BaseModel):
|
|
13
13
|
search_text: str = Field(..., description="The text to search for in the Azure Search index.")
|
|
14
|
-
limit: int = Field(10, description="The number of results to return.")
|
|
14
|
+
limit: int = Field(10, description="The number of results to return.", gt=0)
|
|
15
15
|
selected_fields: Optional[List[str]] = Field(None, description="The fields to retrieve from the document.")
|
|
16
16
|
|
|
17
17
|
class AzureDocumentInput(BaseModel):
|
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}")
|
|
@@ -2,6 +2,7 @@ import copy
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import time
|
|
5
|
+
from enum import Enum
|
|
5
6
|
from typing import Any, Optional, List, Dict, Generator
|
|
6
7
|
|
|
7
8
|
from langchain_core.callbacks import dispatch_custom_event
|
|
@@ -16,13 +17,17 @@ from ..runtime.utils.utils import IndexerKeywords
|
|
|
16
17
|
|
|
17
18
|
logger = logging.getLogger(__name__)
|
|
18
19
|
|
|
19
|
-
DEFAULT_CUT_OFF = 0.
|
|
20
|
+
DEFAULT_CUT_OFF = 0.1
|
|
21
|
+
INDEX_META_UPDATE_INTERVAL = 600.0
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
class IndexTools(str, Enum):
|
|
24
|
+
"""Enum for index-related tool names."""
|
|
25
|
+
INDEX_DATA = "index_data"
|
|
26
|
+
SEARCH_INDEX = "search_index"
|
|
27
|
+
STEPBACK_SEARCH_INDEX = "stepback_search_index"
|
|
28
|
+
STEPBACK_SUMMARY_INDEX = "stepback_summary_index"
|
|
29
|
+
REMOVE_INDEX = "remove_index"
|
|
30
|
+
LIST_COLLECTIONS = "list_collections"
|
|
26
31
|
|
|
27
32
|
RemoveIndexParams = create_model(
|
|
28
33
|
"RemoveIndexParams",
|
|
@@ -41,7 +46,7 @@ BaseSearchParams = create_model(
|
|
|
41
46
|
examples=["{\"key\": \"value\"}", "{\"status\": \"active\"}"]
|
|
42
47
|
)),
|
|
43
48
|
cut_off=(Optional[float], Field(description="Cut-off score for search results", default=DEFAULT_CUT_OFF, ge=0, le=1)),
|
|
44
|
-
search_top=(Optional[int], Field(description="Number of top results to return", default=10)),
|
|
49
|
+
search_top=(Optional[int], Field(description="Number of top results to return", default=10, gt=0)),
|
|
45
50
|
full_text_search=(Optional[Dict[str, Any]], Field(
|
|
46
51
|
description="Full text search parameters. Can be a dictionary with search options.",
|
|
47
52
|
default=None
|
|
@@ -71,7 +76,7 @@ BaseStepbackSearchParams = create_model(
|
|
|
71
76
|
examples=["{\"key\": \"value\"}", "{\"status\": \"active\"}"]
|
|
72
77
|
)),
|
|
73
78
|
cut_off=(Optional[float], Field(description="Cut-off score for search results", default=DEFAULT_CUT_OFF, ge=0, le=1)),
|
|
74
|
-
search_top=(Optional[int], Field(description="Number of top results to return", default=10)),
|
|
79
|
+
search_top=(Optional[int], Field(description="Number of top results to return", default=10, gt=0)),
|
|
75
80
|
full_text_search=(Optional[Dict[str, Any]], Field(
|
|
76
81
|
description="Full text search parameters. Can be a dictionary with search options.",
|
|
77
82
|
default=None
|
|
@@ -90,16 +95,6 @@ BaseStepbackSearchParams = create_model(
|
|
|
90
95
|
)),
|
|
91
96
|
)
|
|
92
97
|
|
|
93
|
-
BaseIndexDataParams = create_model(
|
|
94
|
-
"indexData",
|
|
95
|
-
__base__=BaseIndexParams,
|
|
96
|
-
clean_index=(Optional[bool], Field(default=False,
|
|
97
|
-
description="Optional flag to enforce clean existing index before indexing new data")),
|
|
98
|
-
progress_step=(Optional[int], Field(default=10, ge=0, le=100,
|
|
99
|
-
description="Optional step size for progress reporting during indexing")),
|
|
100
|
-
chunking_config=(Optional[dict], Field(description="Chunking tool configuration", default=loaders_allowed_to_override)),
|
|
101
|
-
)
|
|
102
|
-
|
|
103
98
|
|
|
104
99
|
class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
105
100
|
"""Base class for tool API wrappers that support vector store functionality."""
|
|
@@ -157,6 +152,16 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
157
152
|
clean_index = kwargs.get("clean_index")
|
|
158
153
|
chunking_tool = kwargs.get("chunking_tool")
|
|
159
154
|
chunking_config = kwargs.get("chunking_config")
|
|
155
|
+
|
|
156
|
+
# Store the interval in a private dict to avoid Pydantic field errors
|
|
157
|
+
if not hasattr(self, "_index_meta_config"):
|
|
158
|
+
self._index_meta_config: Dict[str, Any] = {}
|
|
159
|
+
|
|
160
|
+
self._index_meta_config["update_interval"] = kwargs.get(
|
|
161
|
+
"meta_update_interval",
|
|
162
|
+
INDEX_META_UPDATE_INTERVAL,
|
|
163
|
+
)
|
|
164
|
+
|
|
160
165
|
result = {"count": 0}
|
|
161
166
|
#
|
|
162
167
|
try:
|
|
@@ -164,6 +169,7 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
164
169
|
self._clean_index(index_name)
|
|
165
170
|
#
|
|
166
171
|
self.index_meta_init(index_name, kwargs)
|
|
172
|
+
self._emit_index_event(index_name)
|
|
167
173
|
#
|
|
168
174
|
self._log_tool_event(f"Indexing data into collection with suffix '{index_name}'. It can take some time...")
|
|
169
175
|
self._log_tool_event(f"Loading the documents to index...{kwargs}")
|
|
@@ -179,18 +185,26 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
179
185
|
self._save_index_generator(documents, documents_count, chunking_tool, chunking_config, index_name=index_name, result=result)
|
|
180
186
|
#
|
|
181
187
|
results_count = result["count"]
|
|
182
|
-
|
|
188
|
+
# Final update should always be forced
|
|
189
|
+
self.index_meta_update(index_name, IndexerKeywords.INDEX_META_COMPLETED.value, results_count, update_force=True, error=None)
|
|
183
190
|
self._emit_index_event(index_name)
|
|
184
191
|
#
|
|
185
192
|
return {"status": "ok", "message": f"successfully indexed {results_count} documents" if results_count > 0
|
|
186
193
|
else "no new documents to index"}
|
|
187
194
|
except Exception as e:
|
|
188
|
-
|
|
189
|
-
|
|
195
|
+
# Do maximum effort at least send custom event for supposed changed status
|
|
196
|
+
msg = str(e)
|
|
197
|
+
try:
|
|
198
|
+
# Error update should also be forced and include the error message
|
|
199
|
+
self.index_meta_update(index_name, IndexerKeywords.INDEX_META_FAILED.value, result["count"], update_force=True, error=msg)
|
|
200
|
+
except Exception as ie:
|
|
201
|
+
logger.error(f"Failed to update index meta status to FAILED for index '{index_name}': {ie}")
|
|
202
|
+
msg = f"{msg}; additionally failed to update index meta status to FAILED: {ie}"
|
|
203
|
+
self._emit_index_event(index_name, error=msg)
|
|
190
204
|
raise e
|
|
191
|
-
|
|
192
205
|
|
|
193
206
|
def _save_index_generator(self, base_documents: Generator[Document, None, None], base_total: int, chunking_tool, chunking_config, result, index_name: Optional[str] = None):
|
|
207
|
+
self._ensure_vectorstore_initialized()
|
|
194
208
|
self._log_tool_event(f"Base documents are ready for indexing. {base_total} base documents in total to index.")
|
|
195
209
|
from ..runtime.langchain.interfaces.llm_processor import add_documents
|
|
196
210
|
#
|
|
@@ -206,7 +220,7 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
206
220
|
self._log_tool_event(f"Dependent documents were processed. "
|
|
207
221
|
f"Applying chunking tool '{chunking_tool}' if specified and preparing documents for indexing...")
|
|
208
222
|
documents = self._apply_loaders_chunkers(documents, chunking_tool, chunking_config)
|
|
209
|
-
self._clean_metadata(documents)
|
|
223
|
+
documents = self._clean_metadata(documents)
|
|
210
224
|
|
|
211
225
|
logger.debug(f"Indexing base document #{base_doc_counter}: {base_doc} and all dependent documents: {documents}")
|
|
212
226
|
|
|
@@ -243,6 +257,11 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
243
257
|
logger.debug(msg)
|
|
244
258
|
self._log_tool_event(msg)
|
|
245
259
|
result["count"] += dependent_docs_counter
|
|
260
|
+
# After each base document, try a non-forced meta update; throttling handled inside index_meta_update
|
|
261
|
+
try:
|
|
262
|
+
self.index_meta_update(index_name, IndexerKeywords.INDEX_META_IN_PROGRESS.value, result["count"], update_force=False)
|
|
263
|
+
except Exception as exc: # best-effort, do not break indexing
|
|
264
|
+
logger.warning(f"Failed to update index meta during indexing process for index '{index_name}': {exc}")
|
|
246
265
|
if pg_vector_add_docs_chunk:
|
|
247
266
|
add_documents(vectorstore=self.vectorstore, documents=pg_vector_add_docs_chunk)
|
|
248
267
|
|
|
@@ -308,6 +327,7 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
308
327
|
log_msg: str = "Verification of documents to index started"
|
|
309
328
|
) -> Generator[Document, None, None]:
|
|
310
329
|
"""Generic duplicate reduction logic for documents."""
|
|
330
|
+
self._ensure_vectorstore_initialized()
|
|
311
331
|
self._log_tool_event(log_msg, tool_name="index_documents")
|
|
312
332
|
indexed_data = self._get_indexed_data(index_name)
|
|
313
333
|
indexed_keys = set(indexed_data.keys())
|
|
@@ -350,7 +370,8 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
350
370
|
|
|
351
371
|
def remove_index(self, index_name: str = ""):
|
|
352
372
|
"""Cleans the indexed data in the collection."""
|
|
353
|
-
super()._clean_collection(index_name=index_name)
|
|
373
|
+
super()._clean_collection(index_name=index_name, including_index_meta=True)
|
|
374
|
+
self._emit_index_data_removed_event(index_name)
|
|
354
375
|
return (f"Collection '{index_name}' has been removed from the vector store.\n"
|
|
355
376
|
f"Available collections: {self.list_collections()}") if index_name \
|
|
356
377
|
else "All collections have been removed from the vector store."
|
|
@@ -463,6 +484,7 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
463
484
|
)
|
|
464
485
|
|
|
465
486
|
def index_meta_init(self, index_name: str, index_configuration: dict[str, Any]):
|
|
487
|
+
self._ensure_vectorstore_initialized()
|
|
466
488
|
index_meta = super().get_index_meta(index_name)
|
|
467
489
|
if not index_meta:
|
|
468
490
|
self._log_tool_event(
|
|
@@ -482,12 +504,56 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
482
504
|
"updated_on": created_on,
|
|
483
505
|
"task_id": None,
|
|
484
506
|
"conversation_id": None,
|
|
507
|
+
"toolkit_id": self.toolkit_id,
|
|
508
|
+
# Initialize error field to keep track of the latest failure reason if any
|
|
509
|
+
"error": None,
|
|
485
510
|
}
|
|
486
511
|
metadata["history"] = json.dumps([metadata])
|
|
487
512
|
index_meta_doc = Document(page_content=f"{IndexerKeywords.INDEX_META_TYPE.value}_{index_name}", metadata=metadata)
|
|
488
513
|
add_documents(vectorstore=self.vectorstore, documents=[index_meta_doc])
|
|
489
514
|
|
|
490
|
-
def index_meta_update(self, index_name: str, state: str, result: int):
|
|
515
|
+
def index_meta_update(self, index_name: str, state: str, result: int, update_force: bool = True, interval: Optional[float] = None, error: Optional[str] = None):
|
|
516
|
+
"""Update `index_meta` document with optional time-based throttling.
|
|
517
|
+
|
|
518
|
+
Args:
|
|
519
|
+
index_name: Index name to update meta for.
|
|
520
|
+
state: New state value for the `index_meta` record.
|
|
521
|
+
result: Number of processed documents to store in the `updated` field.
|
|
522
|
+
update_force: If `True`, perform the update unconditionally, ignoring throttling.
|
|
523
|
+
If `False`, perform the update only when the effective time interval has passed.
|
|
524
|
+
interval: Optional custom interval (in seconds) for this call when `update_force` is `False`.
|
|
525
|
+
If `None`, falls back to the value stored in `self._index_meta_config["update_interval"]`
|
|
526
|
+
if present, otherwise uses `INDEX_META_UPDATE_INTERVAL`.
|
|
527
|
+
error: Optional error message to record when the state represents a failed index.
|
|
528
|
+
"""
|
|
529
|
+
self._ensure_vectorstore_initialized()
|
|
530
|
+
if not hasattr(self, "_index_meta_last_update_time"):
|
|
531
|
+
self._index_meta_last_update_time: Dict[str, float] = {}
|
|
532
|
+
|
|
533
|
+
if not update_force:
|
|
534
|
+
# Resolve effective interval:
|
|
535
|
+
# 1\) explicit arg
|
|
536
|
+
# 2\) value from `_index_meta_config`
|
|
537
|
+
# 3\) default constant
|
|
538
|
+
cfg_interval = None
|
|
539
|
+
if hasattr(self, "_index_meta_config"):
|
|
540
|
+
cfg_interval = self._index_meta_config.get("update_interval")
|
|
541
|
+
|
|
542
|
+
eff_interval = (
|
|
543
|
+
interval
|
|
544
|
+
if interval is not None
|
|
545
|
+
else (cfg_interval if cfg_interval is not None else INDEX_META_UPDATE_INTERVAL)
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
last_time = self._index_meta_last_update_time.get(index_name)
|
|
549
|
+
now = time.time()
|
|
550
|
+
if last_time is not None and (now - last_time) < eff_interval:
|
|
551
|
+
return
|
|
552
|
+
self._index_meta_last_update_time[index_name] = now
|
|
553
|
+
else:
|
|
554
|
+
# For forced updates, always refresh last update time
|
|
555
|
+
self._index_meta_last_update_time[index_name] = time.time()
|
|
556
|
+
|
|
491
557
|
index_meta_raw = super().get_index_meta(index_name)
|
|
492
558
|
from ..runtime.langchain.interfaces.llm_processor import add_documents
|
|
493
559
|
#
|
|
@@ -497,6 +563,12 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
497
563
|
metadata["updated"] = result
|
|
498
564
|
metadata["state"] = state
|
|
499
565
|
metadata["updated_on"] = time.time()
|
|
566
|
+
# Attach error if provided, else clear on success
|
|
567
|
+
if error is not None:
|
|
568
|
+
metadata["error"] = error
|
|
569
|
+
elif state == IndexerKeywords.INDEX_META_COMPLETED.value:
|
|
570
|
+
# Clear previous error on successful completion
|
|
571
|
+
metadata["error"] = None
|
|
500
572
|
#
|
|
501
573
|
history_raw = metadata.pop("history", "[]")
|
|
502
574
|
try:
|
|
@@ -545,11 +617,12 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
545
617
|
event_data = {
|
|
546
618
|
"id": index_meta.get("id"),
|
|
547
619
|
"index_name": index_name,
|
|
548
|
-
"state": metadata.get("state"),
|
|
620
|
+
"state": "failed" if error is not None else metadata.get("state"),
|
|
549
621
|
"error": error,
|
|
550
622
|
"reindex": is_reindex,
|
|
551
623
|
"indexed": metadata.get("indexed", 0),
|
|
552
624
|
"updated": metadata.get("updated", 0),
|
|
625
|
+
"toolkit_id": metadata.get("toolkit_id"),
|
|
553
626
|
}
|
|
554
627
|
|
|
555
628
|
# Emit the event
|
|
@@ -562,57 +635,109 @@ class BaseIndexerToolkit(VectorStoreWrapperBase):
|
|
|
562
635
|
except Exception as e:
|
|
563
636
|
logger.warning(f"Failed to emit index_data_status event: {e}")
|
|
564
637
|
|
|
638
|
+
def _emit_index_data_removed_event(self, index_name: str):
|
|
639
|
+
"""
|
|
640
|
+
Emit custom event for index data removing.
|
|
641
|
+
|
|
642
|
+
Args:
|
|
643
|
+
index_name: The name of the index
|
|
644
|
+
toolkit_id: The toolkit identifier
|
|
645
|
+
"""
|
|
646
|
+
# Build event message
|
|
647
|
+
event_data = {
|
|
648
|
+
"index_name": index_name,
|
|
649
|
+
"toolkit_id": self.toolkit_id,
|
|
650
|
+
"project_id": self.alita.project_id,
|
|
651
|
+
}
|
|
652
|
+
# Emit the event
|
|
653
|
+
try:
|
|
654
|
+
dispatch_custom_event("index_data_removed", event_data)
|
|
655
|
+
logger.debug(
|
|
656
|
+
f"Emitted index_data_removed event for index "
|
|
657
|
+
f"'{index_name}': {event_data}"
|
|
658
|
+
)
|
|
659
|
+
except Exception as e:
|
|
660
|
+
logger.warning(f"Failed to emit index_data_removed event: {e}")
|
|
661
|
+
|
|
565
662
|
def get_available_tools(self):
|
|
566
663
|
"""
|
|
567
664
|
Returns the standardized vector search tools (search operations only).
|
|
568
665
|
Index operations are toolkit-specific and should be added manually to each toolkit.
|
|
569
|
-
|
|
666
|
+
|
|
667
|
+
This method constructs the argument schemas for each tool, merging base parameters with any extra parameters
|
|
668
|
+
defined in the subclass. It also handles the special case for chunking tools and their configuration.
|
|
669
|
+
|
|
570
670
|
Returns:
|
|
571
|
-
List of tool dictionaries with name, ref, description, and args_schema
|
|
671
|
+
list: List of tool dictionaries with name, ref, description, and args_schema.
|
|
572
672
|
"""
|
|
673
|
+
index_params = {
|
|
674
|
+
"index_name": (
|
|
675
|
+
str,
|
|
676
|
+
Field(description="Index name (max 7 characters)", min_length=1, max_length=7)
|
|
677
|
+
),
|
|
678
|
+
"clean_index": (
|
|
679
|
+
Optional[bool],
|
|
680
|
+
Field(default=False, description="Optional flag to enforce clean existing index before indexing new data")
|
|
681
|
+
),
|
|
682
|
+
"progress_step": (
|
|
683
|
+
Optional[int],
|
|
684
|
+
Field(default=10, ge=0, le=100, description="Optional step size for progress reporting during indexing")
|
|
685
|
+
),
|
|
686
|
+
}
|
|
687
|
+
chunking_config = (
|
|
688
|
+
Optional[dict],
|
|
689
|
+
Field(description="Chunking tool configuration", default=loaders_allowed_to_override)
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
index_extra_params = self._index_tool_params() or {}
|
|
693
|
+
chunking_tool = index_extra_params.pop("chunking_tool", None)
|
|
694
|
+
if chunking_tool:
|
|
695
|
+
index_params = {
|
|
696
|
+
**index_params,
|
|
697
|
+
"chunking_tool": chunking_tool,
|
|
698
|
+
}
|
|
699
|
+
index_params["chunking_config"] = chunking_config
|
|
700
|
+
index_args_schema = create_model("IndexData", **index_params, **index_extra_params)
|
|
701
|
+
|
|
573
702
|
return [
|
|
574
703
|
{
|
|
575
|
-
"name":
|
|
576
|
-
"mode":
|
|
704
|
+
"name": IndexTools.INDEX_DATA.value,
|
|
705
|
+
"mode": IndexTools.INDEX_DATA.value,
|
|
577
706
|
"ref": self.index_data,
|
|
578
707
|
"description": "Loads data to index.",
|
|
579
|
-
"args_schema":
|
|
580
|
-
"IndexData",
|
|
581
|
-
__base__=BaseIndexDataParams,
|
|
582
|
-
**self._index_tool_params() if self._index_tool_params() else {}
|
|
583
|
-
)
|
|
708
|
+
"args_schema": index_args_schema,
|
|
584
709
|
},
|
|
585
710
|
{
|
|
586
|
-
"name":
|
|
587
|
-
"mode":
|
|
711
|
+
"name": IndexTools.SEARCH_INDEX.value,
|
|
712
|
+
"mode": IndexTools.SEARCH_INDEX.value,
|
|
588
713
|
"ref": self.search_index,
|
|
589
714
|
"description": self.search_index.__doc__,
|
|
590
715
|
"args_schema": BaseSearchParams
|
|
591
716
|
},
|
|
592
717
|
{
|
|
593
|
-
"name":
|
|
594
|
-
"mode":
|
|
718
|
+
"name": IndexTools.STEPBACK_SEARCH_INDEX.value,
|
|
719
|
+
"mode": IndexTools.STEPBACK_SEARCH_INDEX.value,
|
|
595
720
|
"ref": self.stepback_search_index,
|
|
596
721
|
"description": self.stepback_search_index.__doc__,
|
|
597
722
|
"args_schema": BaseStepbackSearchParams
|
|
598
723
|
},
|
|
599
724
|
{
|
|
600
|
-
"name":
|
|
601
|
-
"mode":
|
|
725
|
+
"name": IndexTools.STEPBACK_SUMMARY_INDEX.value,
|
|
726
|
+
"mode": IndexTools.STEPBACK_SUMMARY_INDEX.value,
|
|
602
727
|
"ref": self.stepback_summary_index,
|
|
603
728
|
"description": self.stepback_summary_index.__doc__,
|
|
604
729
|
"args_schema": BaseStepbackSearchParams
|
|
605
730
|
},
|
|
606
731
|
{
|
|
607
|
-
"name":
|
|
608
|
-
"mode":
|
|
732
|
+
"name": IndexTools.REMOVE_INDEX.value,
|
|
733
|
+
"mode": IndexTools.REMOVE_INDEX.value,
|
|
609
734
|
"ref": self.remove_index,
|
|
610
735
|
"description": self.remove_index.__doc__,
|
|
611
736
|
"args_schema": RemoveIndexParams
|
|
612
737
|
},
|
|
613
738
|
{
|
|
614
|
-
"name":
|
|
615
|
-
"mode":
|
|
739
|
+
"name": IndexTools.LIST_COLLECTIONS.value,
|
|
740
|
+
"mode": IndexTools.LIST_COLLECTIONS.value,
|
|
616
741
|
"ref": self.list_collections,
|
|
617
742
|
"description": self.list_collections.__doc__,
|
|
618
743
|
# No parameters
|
|
@@ -9,16 +9,17 @@ 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
|
|
16
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
name = "bitbucket"
|
|
19
20
|
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
+
def get_toolkit(tool):
|
|
22
23
|
return AlitaBitbucketToolkit.get_toolkit(
|
|
23
24
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
24
25
|
project=tool['settings']['project'],
|
|
@@ -33,22 +34,23 @@ def get_tools(tool):
|
|
|
33
34
|
doctype='code',
|
|
34
35
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
35
36
|
toolkit_name=tool.get('toolkit_name')
|
|
36
|
-
)
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
def get_tools(tool):
|
|
40
|
+
return get_toolkit(tool).get_tools()
|
|
37
41
|
|
|
38
42
|
|
|
39
43
|
class AlitaBitbucketToolkit(BaseToolkit):
|
|
40
44
|
tools: List[BaseTool] = []
|
|
41
|
-
toolkit_max_length: int = 0
|
|
42
45
|
|
|
43
46
|
@staticmethod
|
|
44
47
|
def toolkit_config_schema() -> BaseModel:
|
|
45
48
|
selected_tools = {x['name']: x['args_schema'].schema() for x in
|
|
46
49
|
BitbucketAPIWrapper.model_construct().get_available_tools()}
|
|
47
|
-
AlitaBitbucketToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
48
50
|
m = create_model(
|
|
49
51
|
name,
|
|
50
|
-
project=(str, Field(description="Project/Workspace"
|
|
51
|
-
repository=(str, Field(description="Repository"
|
|
52
|
+
project=(str, Field(description="Project/Workspace")),
|
|
53
|
+
repository=(str, Field(description="Repository")),
|
|
52
54
|
branch=(str, Field(description="Main branch", default="main")),
|
|
53
55
|
cloud=(Optional[bool], Field(description="Hosting Option", default=None)),
|
|
54
56
|
bitbucket_configuration=(BitbucketConfiguration, Field(description="Bitbucket Configuration", json_schema_extra={'configuration_types': ['bitbucket']})),
|
|
@@ -61,7 +63,6 @@ class AlitaBitbucketToolkit(BaseToolkit):
|
|
|
61
63
|
'metadata':
|
|
62
64
|
{
|
|
63
65
|
"label": "Bitbucket", "icon_url": "bitbucket-icon.svg",
|
|
64
|
-
"max_length": AlitaBitbucketToolkit.toolkit_max_length,
|
|
65
66
|
"categories": ["code repositories"],
|
|
66
67
|
"extra_categories": ["bitbucket", "git", "repository", "code", "version control"],
|
|
67
68
|
}
|
|
@@ -100,17 +101,21 @@ class AlitaBitbucketToolkit(BaseToolkit):
|
|
|
100
101
|
}
|
|
101
102
|
bitbucket_api_wrapper = BitbucketAPIWrapper(**wrapper_payload)
|
|
102
103
|
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
104
|
tools = []
|
|
105
105
|
for tool in available_tools:
|
|
106
106
|
if selected_tools:
|
|
107
107
|
if tool['name'] not in selected_tools:
|
|
108
108
|
continue
|
|
109
|
+
description = tool["description"] + f"\nrepo: {bitbucket_api_wrapper.repository}"
|
|
110
|
+
if toolkit_name:
|
|
111
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
112
|
+
description = description[:1000]
|
|
109
113
|
tools.append(BaseAction(
|
|
110
114
|
api_wrapper=bitbucket_api_wrapper,
|
|
111
|
-
name=
|
|
112
|
-
description=
|
|
113
|
-
args_schema=tool["args_schema"]
|
|
115
|
+
name=tool["name"],
|
|
116
|
+
description=description,
|
|
117
|
+
args_schema=tool["args_schema"],
|
|
118
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
114
119
|
))
|
|
115
120
|
return cls(tools=tools)
|
|
116
121
|
|