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, ConfigDict, Field, SecretStr
|
|
|
6
6
|
from .api_wrapper import KubernetesApiWrapper
|
|
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 = "kubernetes"
|
|
12
12
|
|
|
@@ -21,12 +21,10 @@ def get_tools(tool):
|
|
|
21
21
|
|
|
22
22
|
class KubernetesToolkit(BaseToolkit):
|
|
23
23
|
tools: list[BaseTool] = []
|
|
24
|
-
toolkit_max_length: int = 0
|
|
25
24
|
|
|
26
25
|
@staticmethod
|
|
27
26
|
def toolkit_config_schema() -> BaseModel:
|
|
28
27
|
selected_tools = {x['name']: x['args_schema'].schema() for x in KubernetesApiWrapper.model_construct().get_available_tools()}
|
|
29
|
-
KubernetesToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
30
28
|
return create_model(
|
|
31
29
|
name,
|
|
32
30
|
url=(str, Field(default="", title="Cluster URL", description="The URL of the Kubernetes cluster")),
|
|
@@ -51,15 +49,19 @@ class KubernetesToolkit(BaseToolkit):
|
|
|
51
49
|
kubernetes_api_wrapper = KubernetesApiWrapper(**kwargs)
|
|
52
50
|
available_tools = kubernetes_api_wrapper.get_available_tools()
|
|
53
51
|
tools = []
|
|
54
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
55
52
|
for tool in available_tools:
|
|
56
53
|
if selected_tools and tool["name"] not in selected_tools:
|
|
57
54
|
continue
|
|
55
|
+
description = tool["description"]
|
|
56
|
+
if toolkit_name:
|
|
57
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
58
|
+
description = description[:1000]
|
|
58
59
|
tools.append(BaseAction(
|
|
59
60
|
api_wrapper=kubernetes_api_wrapper,
|
|
60
|
-
name=
|
|
61
|
-
description=
|
|
62
|
-
args_schema=tool["args_schema"]
|
|
61
|
+
name=tool["name"],
|
|
62
|
+
description=description,
|
|
63
|
+
args_schema=tool["args_schema"],
|
|
64
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
63
65
|
))
|
|
64
66
|
return cls(tools=tools)
|
|
65
67
|
|
|
@@ -5,7 +5,7 @@ from pydantic import BaseModel, create_model, Field
|
|
|
5
5
|
|
|
6
6
|
from .api_wrapper import PythonLinter
|
|
7
7
|
from ...base.tool import BaseAction
|
|
8
|
-
from ...utils import clean_string,
|
|
8
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
9
9
|
|
|
10
10
|
name = "python_linter"
|
|
11
11
|
|
|
@@ -19,11 +19,9 @@ def get_tools(tool):
|
|
|
19
19
|
|
|
20
20
|
class PythonLinterToolkit(BaseToolkit):
|
|
21
21
|
tools: list[BaseTool] = []
|
|
22
|
-
toolkit_max_length: int = 0
|
|
23
22
|
|
|
24
23
|
@staticmethod
|
|
25
24
|
def toolkit_config_schema() -> BaseModel:
|
|
26
|
-
PythonLinterToolkit.toolkit_max_length = get_max_toolkit_length([])
|
|
27
25
|
return create_model(
|
|
28
26
|
name,
|
|
29
27
|
error_codes=(str, Field(description="Error codes to be used by the linter")),
|
|
@@ -39,16 +37,19 @@ class PythonLinterToolkit(BaseToolkit):
|
|
|
39
37
|
python_linter = PythonLinter(**kwargs)
|
|
40
38
|
available_tools = python_linter.get_available_tools()
|
|
41
39
|
tools = []
|
|
42
|
-
toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
43
|
-
prefix = clean_string(toolkit_name, PythonLinterToolkit.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
44
40
|
for tool in available_tools:
|
|
45
41
|
if selected_tools and tool["name"] not in selected_tools:
|
|
46
42
|
continue
|
|
43
|
+
description = tool["description"]
|
|
44
|
+
if toolkit_name:
|
|
45
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
46
|
+
description = description[:1000]
|
|
47
47
|
tools.append(BaseAction(
|
|
48
48
|
api_wrapper=python_linter,
|
|
49
|
-
name=
|
|
50
|
-
description=
|
|
51
|
-
args_schema=tool["args_schema"]
|
|
49
|
+
name=tool["name"],
|
|
50
|
+
description=description,
|
|
51
|
+
args_schema=tool["args_schema"],
|
|
52
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
52
53
|
))
|
|
53
54
|
return cls(tools=tools)
|
|
54
55
|
|
|
@@ -4,8 +4,9 @@ def search_format(items):
|
|
|
4
4
|
results = []
|
|
5
5
|
for (doc, score) in items:
|
|
6
6
|
res_chunk = ''
|
|
7
|
-
language = get_programming_language(get_file_extension(doc.metadata
|
|
8
|
-
|
|
7
|
+
language = get_programming_language(get_file_extension(doc.metadata.get("filename", "unknown")))
|
|
8
|
+
method_name = doc.metadata.get("method_name", "text")
|
|
9
|
+
res_chunk += doc.metadata.get("filename", "unknown") + " -> " + method_name + " (score: " + str(score) + ")"
|
|
9
10
|
res_chunk += "\n\n```" + language.value + "\n"+ doc.page_content + "\n```\n\n"
|
|
10
11
|
results.append(res_chunk)
|
|
11
12
|
return results
|
|
@@ -5,7 +5,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
5
5
|
from .api_wrapper import SonarApiWrapper
|
|
6
6
|
from ...base.tool import BaseAction
|
|
7
7
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
8
|
-
from ...utils import clean_string,
|
|
8
|
+
from ...utils import clean_string, get_max_toolkit_length
|
|
9
9
|
from ....configurations.sonar import SonarConfiguration
|
|
10
10
|
|
|
11
11
|
name = "sonar"
|
|
@@ -21,12 +21,10 @@ def get_tools(tool):
|
|
|
21
21
|
|
|
22
22
|
class SonarToolkit(BaseToolkit):
|
|
23
23
|
tools: list[BaseTool] = []
|
|
24
|
-
toolkit_max_length: int = 0
|
|
25
24
|
|
|
26
25
|
@staticmethod
|
|
27
26
|
def toolkit_config_schema() -> BaseModel:
|
|
28
27
|
selected_tools = {x['name']: x['args_schema'].schema() for x in SonarApiWrapper.model_construct().get_available_tools()}
|
|
29
|
-
SonarToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
30
28
|
return create_model(
|
|
31
29
|
name,
|
|
32
30
|
sonar_project_name=(str, Field(description="Project name of the desired repository")),
|
|
@@ -55,15 +53,19 @@ class SonarToolkit(BaseToolkit):
|
|
|
55
53
|
sonar_api_wrapper = SonarApiWrapper(**wrapper_payload)
|
|
56
54
|
available_tools = sonar_api_wrapper.get_available_tools()
|
|
57
55
|
tools = []
|
|
58
|
-
prefix = clean_string(toolkit_name, SonarToolkit.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
59
56
|
for tool in available_tools:
|
|
60
57
|
if selected_tools and tool["name"] not in selected_tools:
|
|
61
58
|
continue
|
|
59
|
+
description = tool["description"]
|
|
60
|
+
if toolkit_name:
|
|
61
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
62
|
+
description = description[:1000]
|
|
62
63
|
tools.append(BaseAction(
|
|
63
64
|
api_wrapper=sonar_api_wrapper,
|
|
64
|
-
name=
|
|
65
|
-
description=
|
|
66
|
-
args_schema=tool["args_schema"]
|
|
65
|
+
name=tool["name"],
|
|
66
|
+
description=description,
|
|
67
|
+
args_schema=tool["args_schema"],
|
|
68
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
67
69
|
))
|
|
68
70
|
return cls(tools=tools)
|
|
69
71
|
|
|
@@ -6,14 +6,14 @@ from ..base.tool import BaseAction
|
|
|
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, parse_list, check_connection_response
|
|
10
10
|
from ...configurations.confluence import ConfluenceConfiguration
|
|
11
11
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
12
12
|
import requests
|
|
13
13
|
|
|
14
14
|
name = "confluence"
|
|
15
15
|
|
|
16
|
-
def
|
|
16
|
+
def get_toolkit(tool):
|
|
17
17
|
return ConfluenceToolkit().get_toolkit(
|
|
18
18
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
19
19
|
space=tool['settings'].get('space', None),
|
|
@@ -33,18 +33,19 @@ def get_tools(tool):
|
|
|
33
33
|
doctype='doc',
|
|
34
34
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
35
35
|
vectorstore_type="PGVector"
|
|
36
|
-
)
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def get_tools(tool):
|
|
39
|
+
return get_toolkit(tool).get_tools()
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
class ConfluenceToolkit(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
|
ConfluenceAPIWrapper.model_construct().get_available_tools()}
|
|
47
|
-
ConfluenceToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
48
49
|
|
|
49
50
|
@check_connection_response
|
|
50
51
|
def check_connection(self):
|
|
@@ -94,7 +95,6 @@ class ConfluenceToolkit(BaseToolkit):
|
|
|
94
95
|
'metadata': {
|
|
95
96
|
"label": "Confluence",
|
|
96
97
|
"icon_url": None,
|
|
97
|
-
"max_length": ConfluenceToolkit.toolkit_max_length,
|
|
98
98
|
"categories": ["documentation"],
|
|
99
99
|
"extra_categories": ["confluence", "wiki", "knowledge base", "documentation", "atlassian"]
|
|
100
100
|
}
|
|
@@ -115,18 +115,23 @@ class ConfluenceToolkit(BaseToolkit):
|
|
|
115
115
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
116
116
|
}
|
|
117
117
|
confluence_api_wrapper = ConfluenceAPIWrapper(**wrapper_payload)
|
|
118
|
-
prefix = clean_string(toolkit_name, ConfluenceToolkit.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
119
118
|
available_tools = confluence_api_wrapper.get_available_tools()
|
|
120
119
|
tools = []
|
|
121
120
|
for tool in available_tools:
|
|
122
121
|
if selected_tools:
|
|
123
122
|
if tool["name"] not in selected_tools:
|
|
124
123
|
continue
|
|
124
|
+
description = tool["description"]
|
|
125
|
+
if toolkit_name:
|
|
126
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
127
|
+
description = f"Confluence space: {confluence_api_wrapper.space}\n{description}"
|
|
128
|
+
description = description[:1000]
|
|
125
129
|
tools.append(BaseAction(
|
|
126
130
|
api_wrapper=confluence_api_wrapper,
|
|
127
|
-
name=
|
|
128
|
-
description=
|
|
129
|
-
args_schema=tool["args_schema"]
|
|
131
|
+
name=tool["name"],
|
|
132
|
+
description=description,
|
|
133
|
+
args_schema=tool["args_schema"],
|
|
134
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
130
135
|
))
|
|
131
136
|
return cls(tools=tools)
|
|
132
137
|
|
|
@@ -480,21 +480,69 @@ class ConfluenceAPIWrapper(NonCodeIndexerToolkit):
|
|
|
480
480
|
"""Gets pages with specific label in the Confluence space."""
|
|
481
481
|
|
|
482
482
|
start = 0
|
|
483
|
-
pages_info = []
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
483
|
+
pages_info: List[Dict[str, Any]] = []
|
|
484
|
+
seen_ids: set[str] = set()
|
|
485
|
+
|
|
486
|
+
# Use a while-loop driven by unique pages collected and
|
|
487
|
+
# presence of additional results instead of a fixed number
|
|
488
|
+
# of iterations based purely on max_pages/limit.
|
|
489
|
+
while len(pages_info) < (self.max_pages or 0):
|
|
490
|
+
pages = self.client.get_all_pages_by_label(
|
|
491
|
+
label,
|
|
492
|
+
start=start,
|
|
493
|
+
limit=self.limit,
|
|
494
|
+
) # , expand="body.view.value"
|
|
487
495
|
if not pages:
|
|
488
496
|
break
|
|
489
497
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
498
|
+
# Collect only ids we haven't processed yet to avoid
|
|
499
|
+
# calling get_page_by_id multiple times for the same
|
|
500
|
+
# Confluence page.
|
|
501
|
+
new_ids: List[str] = []
|
|
502
|
+
for p in pages:
|
|
503
|
+
page_id = p["id"] if isinstance(p, dict) else getattr(p, "id", None)
|
|
504
|
+
if page_id is None:
|
|
505
|
+
continue
|
|
506
|
+
if page_id in seen_ids:
|
|
507
|
+
continue
|
|
508
|
+
seen_ids.add(page_id)
|
|
509
|
+
new_ids.append(page_id)
|
|
510
|
+
|
|
511
|
+
if new_ids:
|
|
512
|
+
for page in self.get_pages_by_id(new_ids):
|
|
513
|
+
meta = getattr(page, "metadata", {}) or {}
|
|
514
|
+
page_id = meta.get("id")
|
|
515
|
+
page_title = meta.get("title")
|
|
516
|
+
page_url = meta.get("source")
|
|
517
|
+
content = getattr(page, "page_content", None)
|
|
518
|
+
|
|
519
|
+
if page_id is None:
|
|
520
|
+
continue
|
|
521
|
+
|
|
522
|
+
pages_info.append(
|
|
523
|
+
{
|
|
524
|
+
"page_id": page_id,
|
|
525
|
+
"page_title": page_title,
|
|
526
|
+
"page_url": page_url,
|
|
527
|
+
"content": content,
|
|
528
|
+
}
|
|
529
|
+
)
|
|
530
|
+
|
|
531
|
+
# Respect max_pages on unique pages collected.
|
|
532
|
+
if len(pages_info) >= (self.max_pages or 0):
|
|
533
|
+
break
|
|
534
|
+
|
|
535
|
+
# Advance the offset by the requested page size.
|
|
496
536
|
start += self.limit
|
|
497
|
-
|
|
537
|
+
|
|
538
|
+
# Defensive break: if the API returns fewer items than
|
|
539
|
+
# requested, there are likely no more pages to fetch.
|
|
540
|
+
if len(pages) < self.limit:
|
|
541
|
+
break
|
|
542
|
+
|
|
543
|
+
# Slice as an extra safety net in case of any race conditions
|
|
544
|
+
# around the max_pages guard in the loop above.
|
|
545
|
+
return pages_info[: (self.max_pages or len(pages_info))]
|
|
498
546
|
|
|
499
547
|
def is_public_page(self, page: dict) -> bool:
|
|
500
548
|
"""Check if a page is publicly accessible."""
|
|
@@ -896,14 +944,14 @@ class ConfluenceAPIWrapper(NonCodeIndexerToolkit):
|
|
|
896
944
|
|
|
897
945
|
# Re-verify extension filters
|
|
898
946
|
# Check if file should be skipped based on skip_extensions
|
|
899
|
-
if any(re.match(pattern.replace('
|
|
947
|
+
if any(re.match(re.escape(pattern).replace(r'\*', '.*') + '$', title, re.IGNORECASE)
|
|
900
948
|
for pattern in self._skip_extensions):
|
|
901
949
|
continue
|
|
902
950
|
|
|
903
951
|
# Check if file should be included based on include_extensions
|
|
904
952
|
# If include_extensions is empty, process all files (that weren't skipped)
|
|
905
953
|
if self._include_extensions and not (
|
|
906
|
-
any(re.match(pattern.replace('
|
|
954
|
+
any(re.match(re.escape(pattern).replace(r'\*', '.*') + '$', title, re.IGNORECASE)
|
|
907
955
|
for pattern in self._include_extensions)):
|
|
908
956
|
continue
|
|
909
957
|
|
|
@@ -1820,4 +1868,5 @@ class ConfluenceAPIWrapper(NonCodeIndexerToolkit):
|
|
|
1820
1868
|
"description": self.get_page_attachments.__doc__,
|
|
1821
1869
|
"args_schema": GetPageAttachmentsInput,
|
|
1822
1870
|
}
|
|
1823
|
-
]
|
|
1871
|
+
]
|
|
1872
|
+
|
|
@@ -5,7 +5,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
5
5
|
|
|
6
6
|
from .api_wrapper import OpenApiWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
|
-
from ..utils import clean_string
|
|
8
|
+
from ..utils import clean_string
|
|
9
9
|
|
|
10
10
|
name = "openapi"
|
|
11
11
|
|
|
@@ -43,15 +43,21 @@ class OpenApiToolkit(BaseToolkit):
|
|
|
43
43
|
openapi_api_wrapper = OpenApiWrapper(**kwargs)
|
|
44
44
|
available_tools = openapi_api_wrapper.get_available_tools()
|
|
45
45
|
tools = []
|
|
46
|
-
|
|
46
|
+
# Use clean toolkit name for context (max 1000 chars in description)
|
|
47
|
+
toolkit_context = f" [Toolkit: {clean_string(toolkit_name)}]" if toolkit_name else ''
|
|
47
48
|
for tool in available_tools:
|
|
48
49
|
if selected_tools and tool["name"] not in selected_tools:
|
|
49
50
|
continue
|
|
51
|
+
# Add toolkit context to description with character limit
|
|
52
|
+
description = tool["description"]
|
|
53
|
+
if toolkit_context and len(description + toolkit_context) <= 1000:
|
|
54
|
+
description = description + toolkit_context
|
|
50
55
|
tools.append(BaseAction(
|
|
51
56
|
api_wrapper=openapi_api_wrapper,
|
|
52
|
-
name=
|
|
53
|
-
description=
|
|
54
|
-
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 {}
|
|
55
61
|
))
|
|
56
62
|
return cls(tools=tools)
|
|
57
63
|
|
|
@@ -5,7 +5,7 @@ from pydantic import BaseModel, ConfigDict, create_model, Field, SecretStr
|
|
|
5
5
|
|
|
6
6
|
from .api_wrapper import ELITEAElasticApiWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
|
-
from ..utils import clean_string,
|
|
8
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
9
9
|
|
|
10
10
|
name = "elastic"
|
|
11
11
|
|
|
@@ -19,15 +19,13 @@ def get_tools(tool):
|
|
|
19
19
|
|
|
20
20
|
class ElasticToolkit(BaseToolkit):
|
|
21
21
|
tools: list[BaseTool] = []
|
|
22
|
-
toolkit_max_length: int = 0
|
|
23
22
|
|
|
24
23
|
@staticmethod
|
|
25
24
|
def toolkit_config_schema() -> BaseModel:
|
|
26
25
|
selected_tools = {x['name']: x['args_schema'].schema() for x in ELITEAElasticApiWrapper.model_construct().get_available_tools()}
|
|
27
|
-
ElasticToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
28
26
|
return create_model(
|
|
29
27
|
name,
|
|
30
|
-
url=(str, Field(default=None, title="Elasticsearch URL", description="Elasticsearch URL", json_schema_extra={'toolkit_name': True
|
|
28
|
+
url=(str, Field(default=None, title="Elasticsearch URL", description="Elasticsearch URL", json_schema_extra={'toolkit_name': True})),
|
|
31
29
|
api_key=(
|
|
32
30
|
Optional[SecretStr],
|
|
33
31
|
Field(
|
|
@@ -48,15 +46,19 @@ class ElasticToolkit(BaseToolkit):
|
|
|
48
46
|
elastic_api_wrapper = ELITEAElasticApiWrapper(**kwargs)
|
|
49
47
|
available_tools = elastic_api_wrapper.get_available_tools()
|
|
50
48
|
tools = []
|
|
51
|
-
prefix = clean_string(toolkit_name, ElasticToolkit.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
52
49
|
for tool in available_tools:
|
|
53
50
|
if selected_tools and tool["name"] not in selected_tools:
|
|
54
51
|
continue
|
|
52
|
+
description = tool["description"]
|
|
53
|
+
if toolkit_name:
|
|
54
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
55
|
+
description = description[:1000]
|
|
55
56
|
tools.append(BaseAction(
|
|
56
57
|
api_wrapper=elastic_api_wrapper,
|
|
57
|
-
name=
|
|
58
|
-
description=
|
|
59
|
-
args_schema=tool["args_schema"]
|
|
58
|
+
name=tool["name"],
|
|
59
|
+
description=description,
|
|
60
|
+
args_schema=tool["args_schema"],
|
|
61
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
60
62
|
))
|
|
61
63
|
return cls(tools=tools)
|
|
62
64
|
|