alita-sdk 0.3.351__py3-none-any.whl → 0.3.499__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/__init__.py +10 -0
- alita_sdk/cli/__main__.py +17 -0
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +155 -0
- alita_sdk/cli/agent_loader.py +215 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3601 -0
- alita_sdk/cli/callbacks.py +647 -0
- alita_sdk/cli/cli.py +168 -0
- alita_sdk/cli/config.py +306 -0
- 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/formatting.py +182 -0
- alita_sdk/cli/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1256 -0
- alita_sdk/cli/mcp_loader.py +315 -0
- alita_sdk/cli/toolkit.py +327 -0
- alita_sdk/cli/toolkit_loader.py +85 -0
- alita_sdk/cli/tools/__init__.py +43 -0
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +1751 -0
- alita_sdk/cli/tools/planning.py +389 -0
- alita_sdk/cli/tools/terminal.py +414 -0
- alita_sdk/community/__init__.py +64 -8
- alita_sdk/community/inventory/__init__.py +224 -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/visualize.py +1370 -0
- alita_sdk/configurations/bitbucket.py +94 -2
- alita_sdk/configurations/confluence.py +96 -1
- alita_sdk/configurations/gitlab.py +79 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/testrail.py +88 -0
- alita_sdk/configurations/xray.py +93 -0
- alita_sdk/configurations/zephyr_enterprise.py +93 -0
- alita_sdk/configurations/zephyr_essential.py +75 -0
- alita_sdk/runtime/clients/artifact.py +1 -1
- alita_sdk/runtime/clients/client.py +214 -42
- alita_sdk/runtime/clients/mcp_discovery.py +342 -0
- alita_sdk/runtime/clients/mcp_manager.py +262 -0
- alita_sdk/runtime/clients/sandbox_client.py +373 -0
- alita_sdk/runtime/langchain/assistant.py +118 -30
- alita_sdk/runtime/langchain/constants.py +8 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +4 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +41 -12
- alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/constants.py +116 -99
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +2 -2
- alita_sdk/runtime/langchain/langraph_agent.py +307 -71
- alita_sdk/runtime/langchain/utils.py +48 -8
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- alita_sdk/runtime/toolkits/__init__.py +26 -0
- alita_sdk/runtime/toolkits/application.py +9 -2
- alita_sdk/runtime/toolkits/artifact.py +18 -6
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +780 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/tools.py +205 -55
- alita_sdk/runtime/toolkits/vectorstore.py +9 -4
- alita_sdk/runtime/tools/__init__.py +11 -3
- alita_sdk/runtime/tools/application.py +7 -0
- alita_sdk/runtime/tools/artifact.py +225 -12
- alita_sdk/runtime/tools/function.py +95 -5
- alita_sdk/runtime/tools/graph.py +10 -4
- alita_sdk/runtime/tools/image_generation.py +212 -0
- alita_sdk/runtime/tools/llm.py +494 -102
- alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
- alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
- alita_sdk/runtime/tools/mcp_server_tool.py +4 -4
- 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 -1
- alita_sdk/runtime/tools/sandbox.py +180 -79
- alita_sdk/runtime/tools/vectorstore.py +22 -21
- alita_sdk/runtime/tools/vectorstore_base.py +125 -52
- alita_sdk/runtime/utils/AlitaCallback.py +106 -20
- alita_sdk/runtime/utils/mcp_client.py +465 -0
- alita_sdk/runtime/utils/mcp_oauth.py +244 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +405 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +40 -13
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +12 -0
- alita_sdk/tools/__init__.py +77 -33
- alita_sdk/tools/ado/repos/__init__.py +7 -6
- alita_sdk/tools/ado/repos/repos_wrapper.py +11 -11
- alita_sdk/tools/ado/test_plan/__init__.py +7 -7
- alita_sdk/tools/ado/wiki/__init__.py +7 -11
- alita_sdk/tools/ado/wiki/ado_wrapper.py +89 -15
- alita_sdk/tools/ado/work_item/__init__.py +7 -11
- alita_sdk/tools/ado/work_item/ado_wrapper.py +17 -8
- alita_sdk/tools/advanced_jira_mining/__init__.py +8 -7
- alita_sdk/tools/aws/delta_lake/__init__.py +11 -9
- alita_sdk/tools/azure_ai/search/__init__.py +7 -6
- alita_sdk/tools/base_indexer_toolkit.py +345 -70
- alita_sdk/tools/bitbucket/__init__.py +9 -8
- alita_sdk/tools/bitbucket/api_wrapper.py +50 -6
- alita_sdk/tools/browser/__init__.py +4 -4
- alita_sdk/tools/carrier/__init__.py +4 -6
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +7 -6
- alita_sdk/tools/cloud/azure/__init__.py +7 -6
- alita_sdk/tools/cloud/gcp/__init__.py +7 -6
- alita_sdk/tools/cloud/k8s/__init__.py +7 -6
- alita_sdk/tools/code/linter/__init__.py +7 -7
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +8 -7
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +9 -8
- alita_sdk/tools/confluence/api_wrapper.py +171 -75
- alita_sdk/tools/confluence/loader.py +10 -0
- alita_sdk/tools/custom_open_api/__init__.py +9 -4
- alita_sdk/tools/elastic/__init__.py +8 -7
- alita_sdk/tools/elitea_base.py +492 -52
- alita_sdk/tools/figma/__init__.py +7 -7
- alita_sdk/tools/figma/api_wrapper.py +2 -1
- alita_sdk/tools/github/__init__.py +9 -9
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +62 -2
- alita_sdk/tools/gitlab/__init__.py +8 -8
- alita_sdk/tools/gitlab/api_wrapper.py +135 -33
- alita_sdk/tools/gitlab_org/__init__.py +7 -8
- alita_sdk/tools/google/bigquery/__init__.py +11 -12
- alita_sdk/tools/google_places/__init__.py +8 -7
- alita_sdk/tools/jira/__init__.py +9 -7
- alita_sdk/tools/jira/api_wrapper.py +100 -52
- alita_sdk/tools/keycloak/__init__.py +8 -7
- alita_sdk/tools/localgit/local_git.py +56 -54
- alita_sdk/tools/memory/__init__.py +1 -1
- alita_sdk/tools/non_code_indexer_toolkit.py +3 -2
- alita_sdk/tools/ocr/__init__.py +8 -7
- alita_sdk/tools/openapi/__init__.py +10 -1
- alita_sdk/tools/pandas/__init__.py +8 -7
- alita_sdk/tools/postman/__init__.py +7 -8
- alita_sdk/tools/postman/api_wrapper.py +19 -8
- alita_sdk/tools/postman/postman_analysis.py +8 -1
- alita_sdk/tools/pptx/__init__.py +8 -9
- alita_sdk/tools/qtest/__init__.py +16 -11
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +7 -8
- alita_sdk/tools/report_portal/__init__.py +9 -7
- alita_sdk/tools/salesforce/__init__.py +7 -7
- alita_sdk/tools/servicenow/__init__.py +10 -10
- alita_sdk/tools/sharepoint/__init__.py +7 -6
- alita_sdk/tools/sharepoint/api_wrapper.py +127 -36
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +7 -6
- alita_sdk/tools/sql/__init__.py +8 -7
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +7 -6
- alita_sdk/tools/testrail/__init__.py +8 -9
- alita_sdk/tools/utils/__init__.py +26 -4
- alita_sdk/tools/utils/content_parser.py +88 -60
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +76 -26
- alita_sdk/tools/xray/__init__.py +9 -7
- alita_sdk/tools/zephyr/__init__.py +7 -6
- alita_sdk/tools/zephyr_enterprise/__init__.py +8 -6
- alita_sdk/tools/zephyr_essential/__init__.py +7 -6
- alita_sdk/tools/zephyr_essential/api_wrapper.py +12 -13
- alita_sdk/tools/zephyr_scale/__init__.py +7 -6
- alita_sdk/tools/zephyr_squad/__init__.py +7 -6
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/METADATA +147 -2
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/RECORD +206 -130
- alita_sdk-0.3.499.dist-info/entry_points.txt +2 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/top_level.txt +0 -0
|
@@ -9,26 +9,19 @@ from ...elitea_base import filter_missconfigured_index_tools
|
|
|
9
9
|
from ....configurations.ado import AdoConfiguration
|
|
10
10
|
from ....configurations.pgvector import PgVectorConfiguration
|
|
11
11
|
from ...base.tool import BaseAction
|
|
12
|
-
from ...utils import clean_string,
|
|
12
|
+
from ...utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
13
13
|
|
|
14
14
|
name = "azure_devops_wiki"
|
|
15
15
|
name_alias = 'ado_wiki'
|
|
16
16
|
|
|
17
17
|
class AzureDevOpsWikiToolkit(BaseToolkit):
|
|
18
18
|
tools: List[BaseTool] = []
|
|
19
|
-
toolkit_max_length: int = 0
|
|
20
19
|
|
|
21
20
|
@staticmethod
|
|
22
21
|
def toolkit_config_schema() -> BaseModel:
|
|
23
22
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AzureDevOpsApiWrapper.model_construct().get_available_tools()}
|
|
24
|
-
AzureDevOpsWikiToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
25
23
|
m = create_model(
|
|
26
24
|
name_alias,
|
|
27
|
-
name=(str, Field(description="Toolkit name",
|
|
28
|
-
json_schema_extra={
|
|
29
|
-
'toolkit_name': True,
|
|
30
|
-
'max_toolkit_length': AzureDevOpsWikiToolkit.toolkit_max_length})
|
|
31
|
-
),
|
|
32
25
|
ado_configuration=(AdoConfiguration, Field(description="Ado configuration", json_schema_extra={'configuration_types': ['ado']})),
|
|
33
26
|
# indexer settings
|
|
34
27
|
pgvector_configuration=(Optional[PgVectorConfiguration], Field(default=None,
|
|
@@ -95,15 +88,18 @@ class AzureDevOpsWikiToolkit(BaseToolkit):
|
|
|
95
88
|
azure_devops_api_wrapper = AzureDevOpsApiWrapper(**wrapper_payload)
|
|
96
89
|
available_tools = azure_devops_api_wrapper.get_available_tools()
|
|
97
90
|
tools = []
|
|
98
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
99
91
|
for tool in available_tools:
|
|
100
92
|
if selected_tools:
|
|
101
93
|
if tool["name"] not in selected_tools:
|
|
102
94
|
continue
|
|
95
|
+
description = tool["description"] + f"\nADO instance: {azure_devops_api_wrapper.organization_url}/{azure_devops_api_wrapper.project}"
|
|
96
|
+
if toolkit_name:
|
|
97
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
98
|
+
description = description[:1000]
|
|
103
99
|
tools.append(BaseAction(
|
|
104
100
|
api_wrapper=azure_devops_api_wrapper,
|
|
105
|
-
name=
|
|
106
|
-
description=
|
|
101
|
+
name=tool["name"],
|
|
102
|
+
description=description,
|
|
107
103
|
args_schema=tool["args_schema"]
|
|
108
104
|
))
|
|
109
105
|
return cls(tools=tools)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import hashlib
|
|
2
2
|
import logging
|
|
3
|
+
import re
|
|
4
|
+
import requests
|
|
3
5
|
from typing import Generator, Literal, Optional
|
|
4
6
|
|
|
5
7
|
from azure.devops.connection import Connection
|
|
@@ -15,8 +17,11 @@ from pydantic import create_model, PrivateAttr, SecretStr
|
|
|
15
17
|
from pydantic import model_validator
|
|
16
18
|
from pydantic.fields import Field
|
|
17
19
|
|
|
20
|
+
import alita_sdk.tools.ado.work_item
|
|
21
|
+
from ..repos import ReposApiWrapper
|
|
18
22
|
from ...non_code_indexer_toolkit import NonCodeIndexerToolkit
|
|
19
23
|
from ...utils.available_tools_decorator import extend_with_parent_available_tools
|
|
24
|
+
from ...utils.content_parser import parse_file_content
|
|
20
25
|
from ....runtime.utils.utils import IndexerKeywords
|
|
21
26
|
|
|
22
27
|
logger = logging.getLogger(__name__)
|
|
@@ -29,13 +34,17 @@ GetWikiInput = create_model(
|
|
|
29
34
|
GetPageByPathInput = create_model(
|
|
30
35
|
"GetPageByPathInput",
|
|
31
36
|
wiki_identified=(str, Field(description="Wiki ID or wiki name")),
|
|
32
|
-
page_name=(str, Field(description="Wiki page path"))
|
|
37
|
+
page_name=(str, Field(description="Wiki page path")),
|
|
38
|
+
image_description_prompt=(Optional[str],
|
|
39
|
+
Field(description="Prompt which is used for image description", default=None))
|
|
33
40
|
)
|
|
34
41
|
|
|
35
42
|
GetPageByIdInput = create_model(
|
|
36
43
|
"GetPageByIdInput",
|
|
37
44
|
wiki_identified=(str, Field(description="Wiki ID or wiki name")),
|
|
38
|
-
page_id=(int, Field(description="Wiki page ID"))
|
|
45
|
+
page_id=(int, Field(description="Wiki page ID")),
|
|
46
|
+
image_description_prompt=(Optional[str],
|
|
47
|
+
Field(description="Prompt which is used for image description", default=None))
|
|
39
48
|
)
|
|
40
49
|
|
|
41
50
|
ModifyPageInput = create_model(
|
|
@@ -43,8 +52,9 @@ ModifyPageInput = create_model(
|
|
|
43
52
|
wiki_identified=(str, Field(description="Wiki ID or wiki name")),
|
|
44
53
|
page_name=(str, Field(description="Wiki page name")),
|
|
45
54
|
page_content=(str, Field(description="Wiki page content")),
|
|
46
|
-
version_identifier=(str, Field(description="Version string identifier (name of tag/branch, SHA1 of commit)")),
|
|
47
|
-
version_type=(Optional[str], Field(description="Version type (branch, tag, or commit). Determines how Id is interpreted", default="branch"))
|
|
55
|
+
version_identifier=(str, Field(description="Version string identifier (name of tag/branch, SHA1 of commit). Usually for wiki the branch is 'wikiMaster'")),
|
|
56
|
+
version_type=(Optional[str], Field(description="Version type (branch, tag, or commit). Determines how Id is interpreted", default="branch")),
|
|
57
|
+
expanded=(Optional[bool], Field(description="Whether to return the full page object or just its simplified version.", default=False))
|
|
48
58
|
)
|
|
49
59
|
|
|
50
60
|
RenamePageInput = create_model(
|
|
@@ -57,6 +67,19 @@ RenamePageInput = create_model(
|
|
|
57
67
|
)
|
|
58
68
|
|
|
59
69
|
|
|
70
|
+
def _format_wiki_page_response(wiki_page_response, expanded: bool = False):
|
|
71
|
+
"""Format wiki page response."""
|
|
72
|
+
try:
|
|
73
|
+
return {
|
|
74
|
+
'eTag': wiki_page_response.eTag,
|
|
75
|
+
'page': wiki_page_response.page.__dict__ if wiki_page_response.page else None
|
|
76
|
+
} if expanded else {"eTag": wiki_page_response.eTag, "id": wiki_page_response.page.id,
|
|
77
|
+
"page": wiki_page_response.page.url}
|
|
78
|
+
except:
|
|
79
|
+
logger.error(f"Unable to format wiki page response: {wiki_page_response}")
|
|
80
|
+
return wiki_page_response
|
|
81
|
+
|
|
82
|
+
|
|
60
83
|
class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
61
84
|
# TODO use ado_configuration instead of organization_url, project and token
|
|
62
85
|
organization_url: str
|
|
@@ -94,24 +117,75 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
|
94
117
|
logger.error(f"Error during the attempt to extract wiki: {str(e)}")
|
|
95
118
|
return ToolException(f"Error during the attempt to extract wiki: {str(e)}")
|
|
96
119
|
|
|
97
|
-
def get_wiki_page_by_path(self, wiki_identified: str, page_name: str):
|
|
120
|
+
def get_wiki_page_by_path(self, wiki_identified: str, page_name: str, image_description_prompt=None):
|
|
98
121
|
"""Extract ADO wiki page content."""
|
|
99
122
|
try:
|
|
100
|
-
return self._client.get_page(project=self.project, wiki_identifier=wiki_identified, path=page_name,
|
|
101
|
-
include_content=True).page.content
|
|
123
|
+
return self._process_images(self._client.get_page(project=self.project, wiki_identifier=wiki_identified, path=page_name,
|
|
124
|
+
include_content=True).page.content,
|
|
125
|
+
image_description_prompt=image_description_prompt)
|
|
102
126
|
except Exception as e:
|
|
103
127
|
logger.error(f"Error during the attempt to extract wiki page: {str(e)}")
|
|
104
128
|
return ToolException(f"Error during the attempt to extract wiki page: {str(e)}")
|
|
105
129
|
|
|
106
|
-
def get_wiki_page_by_id(self, wiki_identified: str, page_id: int):
|
|
130
|
+
def get_wiki_page_by_id(self, wiki_identified: str, page_id: int, image_description_prompt=None):
|
|
107
131
|
"""Extract ADO wiki page content."""
|
|
108
132
|
try:
|
|
109
|
-
return (self._client.get_page_by_id(project=self.project, wiki_identifier=wiki_identified, id=page_id,
|
|
110
|
-
include_content=True).page.content
|
|
133
|
+
return self._process_images(self._client.get_page_by_id(project=self.project, wiki_identifier=wiki_identified, id=page_id,
|
|
134
|
+
include_content=True).page.content,
|
|
135
|
+
image_description_prompt=image_description_prompt)
|
|
111
136
|
except Exception as e:
|
|
112
137
|
logger.error(f"Error during the attempt to extract wiki page: {str(e)}")
|
|
113
138
|
return ToolException(f"Error during the attempt to extract wiki page: {str(e)}")
|
|
114
139
|
|
|
140
|
+
def _process_images(self, page_content: str, image_description_prompt=None):
|
|
141
|
+
|
|
142
|
+
image_pattern = r"!\[(.*?)\]\((.*?)\)"
|
|
143
|
+
matches = re.findall(image_pattern, page_content)
|
|
144
|
+
|
|
145
|
+
for image_name, image_url in matches:
|
|
146
|
+
if image_url.startswith("/.attachments/"):
|
|
147
|
+
try:
|
|
148
|
+
description = self.process_attachment(attachment_url=image_url,
|
|
149
|
+
attachment_name=image_name,
|
|
150
|
+
image_description_prompt=image_description_prompt)
|
|
151
|
+
except Exception as e:
|
|
152
|
+
logger.error(f"Error parsing attachment: {str(e)}")
|
|
153
|
+
description = f"Error parsing attachment: {image_url}"
|
|
154
|
+
else:
|
|
155
|
+
try:
|
|
156
|
+
response = requests.get(image_url)
|
|
157
|
+
response.raise_for_status()
|
|
158
|
+
file_content = response.content
|
|
159
|
+
description = parse_file_content(
|
|
160
|
+
file_content=file_content,
|
|
161
|
+
file_name="image.png",
|
|
162
|
+
llm=self.llm,
|
|
163
|
+
prompt=image_description_prompt
|
|
164
|
+
)
|
|
165
|
+
except Exception as e:
|
|
166
|
+
logger.error(f"Error fetching external image: {str(e)}")
|
|
167
|
+
description = f"Error fetching external image: image_url"
|
|
168
|
+
|
|
169
|
+
new_image_markdown = f""
|
|
170
|
+
page_content = page_content.replace(f"", new_image_markdown)
|
|
171
|
+
return page_content
|
|
172
|
+
|
|
173
|
+
def process_attachment(self, attachment_url, attachment_name, image_description_prompt):
|
|
174
|
+
wiki_master_branch = "wikiMaster"
|
|
175
|
+
repos_wrapper = ReposApiWrapper(organization_url=self.organization_url,
|
|
176
|
+
project=self.project,
|
|
177
|
+
token=self.token.get_secret_value(),
|
|
178
|
+
repository_id="Test_agent.wiki",
|
|
179
|
+
base_branch=wiki_master_branch,
|
|
180
|
+
active_branch=wiki_master_branch)
|
|
181
|
+
attachment_content = repos_wrapper.download_file(path=attachment_url)
|
|
182
|
+
return parse_file_content(
|
|
183
|
+
file_content=attachment_content,
|
|
184
|
+
file_name=attachment_name,
|
|
185
|
+
llm=self.llm,
|
|
186
|
+
prompt=image_description_prompt
|
|
187
|
+
)
|
|
188
|
+
|
|
115
189
|
def delete_page_by_path(self, wiki_identified: str, page_name: str):
|
|
116
190
|
"""Extract ADO wiki page content."""
|
|
117
191
|
try:
|
|
@@ -166,7 +240,7 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
|
166
240
|
logger.error(f"Unable to rename wiki page: {str(e)}")
|
|
167
241
|
return ToolException(f"Unable to rename wiki page: {str(e)}")
|
|
168
242
|
|
|
169
|
-
def modify_wiki_page(self, wiki_identified: str, page_name: str, page_content: str, version_identifier: str, version_type: str = "branch"):
|
|
243
|
+
def modify_wiki_page(self, wiki_identified: str, page_name: str, page_content: str, version_identifier: str, version_type: str = "branch", expanded: Optional[bool] = False):
|
|
170
244
|
"""Create or Update ADO wiki page content."""
|
|
171
245
|
try:
|
|
172
246
|
all_wikis = [wiki.name for wiki in self._client.get_all_wikis(project=self.project)]
|
|
@@ -197,24 +271,24 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
|
197
271
|
return ToolException(f"Unable to extract page by path {page_name}: {str(get_page_e)}")
|
|
198
272
|
|
|
199
273
|
try:
|
|
200
|
-
return self._client.create_or_update_page(
|
|
274
|
+
return _format_wiki_page_response(self._client.create_or_update_page(
|
|
201
275
|
project=self.project,
|
|
202
276
|
wiki_identifier=wiki_identified,
|
|
203
277
|
path=page_name,
|
|
204
278
|
parameters=WikiPageCreateOrUpdateParameters(content=page_content),
|
|
205
279
|
version=version,
|
|
206
280
|
version_descriptor=GitVersionDescriptor(version=version_identifier, version_type=version_type)
|
|
207
|
-
)
|
|
281
|
+
), expanded=expanded)
|
|
208
282
|
except AzureDevOpsServiceError as e:
|
|
209
283
|
if "The version '{0}' either is invalid or does not exist." in str(e):
|
|
210
284
|
# Retry the request without version_descriptor
|
|
211
|
-
return self._client.create_or_update_page(
|
|
285
|
+
return _format_wiki_page_response(wiki_page_response=self._client.create_or_update_page(
|
|
212
286
|
project=self.project,
|
|
213
287
|
wiki_identifier=wiki_identified,
|
|
214
288
|
path=page_name,
|
|
215
289
|
parameters=WikiPageCreateOrUpdateParameters(content=page_content),
|
|
216
290
|
version=version
|
|
217
|
-
)
|
|
291
|
+
), expanded=expanded)
|
|
218
292
|
else:
|
|
219
293
|
raise
|
|
220
294
|
except Exception as e:
|
|
@@ -9,25 +9,18 @@ from ...elitea_base import filter_missconfigured_index_tools
|
|
|
9
9
|
from ....configurations.ado import AdoConfiguration
|
|
10
10
|
from ....configurations.pgvector import PgVectorConfiguration
|
|
11
11
|
from ...base.tool import BaseAction
|
|
12
|
-
from ...utils import clean_string,
|
|
12
|
+
from ...utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
13
13
|
|
|
14
14
|
name = "ado_boards"
|
|
15
15
|
|
|
16
16
|
class AzureDevOpsWorkItemsToolkit(BaseToolkit):
|
|
17
17
|
tools: List[BaseTool] = []
|
|
18
|
-
toolkit_max_length: int = 0
|
|
19
18
|
|
|
20
19
|
@staticmethod
|
|
21
20
|
def toolkit_config_schema() -> BaseModel:
|
|
22
21
|
selected_tools = {x['name']: x['args_schema'].schema() for x in AzureDevOpsApiWrapper.model_construct().get_available_tools()}
|
|
23
|
-
AzureDevOpsWorkItemsToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
24
22
|
m = create_model(
|
|
25
23
|
name,
|
|
26
|
-
name=(str, Field(description="Toolkit name",
|
|
27
|
-
json_schema_extra={
|
|
28
|
-
'toolkit_name': True,
|
|
29
|
-
'max_toolkit_length': AzureDevOpsWorkItemsToolkit.toolkit_max_length})
|
|
30
|
-
),
|
|
31
24
|
ado_configuration=(AdoConfiguration, Field(description="Ado Work Item configuration", json_schema_extra={'configuration_types': ['ado']})),
|
|
32
25
|
limit=(Optional[int], Field(description="ADO plans limit used for limitation of the list with results", default=5)),
|
|
33
26
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
@@ -96,15 +89,18 @@ class AzureDevOpsWorkItemsToolkit(BaseToolkit):
|
|
|
96
89
|
azure_devops_api_wrapper = AzureDevOpsApiWrapper(**wrapper_payload)
|
|
97
90
|
available_tools = azure_devops_api_wrapper.get_available_tools()
|
|
98
91
|
tools = []
|
|
99
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
100
92
|
for tool in available_tools:
|
|
101
93
|
if selected_tools:
|
|
102
94
|
if tool["name"] not in selected_tools:
|
|
103
95
|
continue
|
|
96
|
+
description = tool["description"] + f"\nADO instance: {azure_devops_api_wrapper.organization_url}/{azure_devops_api_wrapper.project}"
|
|
97
|
+
if toolkit_name:
|
|
98
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
99
|
+
description = description[:1000]
|
|
104
100
|
tools.append(BaseAction(
|
|
105
101
|
api_wrapper=azure_devops_api_wrapper,
|
|
106
|
-
name=
|
|
107
|
-
description=
|
|
102
|
+
name=tool["name"],
|
|
103
|
+
description=description,
|
|
108
104
|
args_schema=tool["args_schema"]
|
|
109
105
|
))
|
|
110
106
|
return cls(tools=tools)
|
|
@@ -329,11 +329,14 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
|
329
329
|
parsed_item.update(fields_data)
|
|
330
330
|
|
|
331
331
|
# extract relations if any
|
|
332
|
-
relations_data =
|
|
332
|
+
relations_data = None
|
|
333
|
+
if expand and str(expand).lower() in ("relations", "all"):
|
|
334
|
+
try:
|
|
335
|
+
relations_data = getattr(work_item, 'relations', None)
|
|
336
|
+
except KeyError:
|
|
337
|
+
relations_data = None
|
|
333
338
|
if relations_data:
|
|
334
|
-
parsed_item['relations'] = []
|
|
335
|
-
for relation in relations_data:
|
|
336
|
-
parsed_item['relations'].append(relation.as_dict())
|
|
339
|
+
parsed_item['relations'] = [relation.as_dict() for relation in relations_data]
|
|
337
340
|
|
|
338
341
|
if parse_attachments:
|
|
339
342
|
# describe images in work item fields if present
|
|
@@ -344,13 +347,19 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
|
|
|
344
347
|
for img in images:
|
|
345
348
|
src = img.get('src')
|
|
346
349
|
if src:
|
|
347
|
-
description = self.parse_attachment_by_url(src, image_description_prompt)
|
|
350
|
+
description = self.parse_attachment_by_url(src, image_description_prompt=image_description_prompt)
|
|
348
351
|
img['image-description'] = description
|
|
349
352
|
parsed_item[field_name] = str(soup)
|
|
350
353
|
# parse attached documents if present
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
+
for relation in parsed_item.get('relations', []):
|
|
355
|
+
# Only process actual file attachments
|
|
356
|
+
if relation.get('rel') == 'AttachedFile':
|
|
357
|
+
file_name = relation.get('attributes', {}).get('name')
|
|
358
|
+
if file_name:
|
|
359
|
+
try:
|
|
360
|
+
relation['content'] = self.parse_attachment_by_url(relation['url'], file_name, image_description_prompt=image_description_prompt)
|
|
361
|
+
except Exception as att_e:
|
|
362
|
+
logger.warning(f"Failed to parse attachment {file_name}: {att_e}")
|
|
354
363
|
|
|
355
364
|
|
|
356
365
|
return parsed_item
|
|
@@ -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,16 +64,19 @@ 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=
|
|
78
|
+
name=tool["name"],
|
|
79
|
+
description=description,
|
|
79
80
|
args_schema=tool["args_schema"]
|
|
80
81
|
))
|
|
81
82
|
return cls(tools=tools)
|
|
@@ -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,11 +115,16 @@ 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"],
|
|
127
129
|
)
|
|
128
130
|
)
|
|
@@ -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,16 +77,19 @@ 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=
|
|
91
|
+
name=tool["name"],
|
|
92
|
+
description=description,
|
|
92
93
|
args_schema=tool["args_schema"]
|
|
93
94
|
))
|
|
94
95
|
return cls(tools=tools)
|