alita-sdk 0.3.457__py3-none-any.whl → 0.3.486__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/__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 +194 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3592 -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 +1665 -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 +169 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/bitbucket.py +0 -3
- alita_sdk/runtime/clients/client.py +99 -26
- alita_sdk/runtime/langchain/assistant.py +4 -2
- alita_sdk/runtime/langchain/constants.py +2 -1
- alita_sdk/runtime/langchain/langraph_agent.py +134 -31
- alita_sdk/runtime/langchain/utils.py +1 -1
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/toolkits/__init__.py +2 -0
- alita_sdk/runtime/toolkits/application.py +1 -1
- alita_sdk/runtime/toolkits/mcp.py +46 -36
- alita_sdk/runtime/toolkits/planning.py +171 -0
- alita_sdk/runtime/toolkits/tools.py +39 -6
- alita_sdk/runtime/tools/function.py +17 -5
- alita_sdk/runtime/tools/llm.py +249 -14
- 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/vectorstore_base.py +41 -6
- alita_sdk/runtime/utils/mcp_oauth.py +80 -0
- alita_sdk/runtime/utils/streamlit.py +6 -10
- alita_sdk/runtime/utils/toolkit_utils.py +19 -4
- alita_sdk/tools/__init__.py +54 -27
- alita_sdk/tools/ado/repos/repos_wrapper.py +1 -2
- alita_sdk/tools/base_indexer_toolkit.py +150 -19
- alita_sdk/tools/bitbucket/__init__.py +2 -2
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +95 -6
- alita_sdk/tools/chunkers/universal_chunker.py +269 -0
- alita_sdk/tools/code_indexer_toolkit.py +55 -22
- alita_sdk/tools/elitea_base.py +86 -21
- alita_sdk/tools/jira/__init__.py +1 -1
- alita_sdk/tools/jira/api_wrapper.py +91 -40
- alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
- alita_sdk/tools/qtest/__init__.py +1 -1
- alita_sdk/tools/qtest/api_wrapper.py +871 -32
- alita_sdk/tools/sharepoint/api_wrapper.py +22 -2
- alita_sdk/tools/sharepoint/authorization_helper.py +17 -1
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +8 -2
- alita_sdk/tools/zephyr_essential/api_wrapper.py +12 -13
- {alita_sdk-0.3.457.dist-info → alita_sdk-0.3.486.dist-info}/METADATA +146 -2
- {alita_sdk-0.3.457.dist-info → alita_sdk-0.3.486.dist-info}/RECORD +102 -40
- alita_sdk-0.3.486.dist-info/entry_points.txt +2 -0
- {alita_sdk-0.3.457.dist-info → alita_sdk-0.3.486.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.457.dist-info → alita_sdk-0.3.486.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.457.dist-info → alita_sdk-0.3.486.dist-info}/top_level.txt +0 -0
|
@@ -453,41 +453,63 @@ class JiraApiWrapper(NonCodeIndexerToolkit):
|
|
|
453
453
|
return super().validate_toolkit(values)
|
|
454
454
|
|
|
455
455
|
def _parse_issues(self, issues: Dict) -> List[dict]:
|
|
456
|
-
parsed = []
|
|
457
|
-
|
|
458
|
-
|
|
456
|
+
parsed: List[dict] = []
|
|
457
|
+
issues_list = issues.get("issues") if isinstance(issues, dict) else None
|
|
458
|
+
if not isinstance(issues_list, list):
|
|
459
|
+
return parsed
|
|
460
|
+
|
|
461
|
+
for issue in issues_list:
|
|
462
|
+
if self.limit and len(parsed) >= self.limit:
|
|
459
463
|
break
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
464
|
+
|
|
465
|
+
issue_fields = issue.get("fields") or {}
|
|
466
|
+
key = issue.get("key", "")
|
|
467
|
+
issue_id = issue.get("id", "")
|
|
468
|
+
|
|
469
|
+
summary = issue_fields.get("summary") or ""
|
|
470
|
+
description = issue_fields.get("description") or ""
|
|
471
|
+
created_raw = issue_fields.get("created") or ""
|
|
472
|
+
created = created_raw[:10] if created_raw else ""
|
|
473
|
+
updated = issue_fields.get("updated") or ""
|
|
474
|
+
duedate = issue_fields.get("duedate")
|
|
475
|
+
|
|
476
|
+
priority_info = issue_fields.get("priority") or {}
|
|
477
|
+
priority = priority_info.get("name") or "None"
|
|
478
|
+
|
|
479
|
+
status_info = issue_fields.get("status") or {}
|
|
480
|
+
status = status_info.get("name") or "Unknown"
|
|
481
|
+
|
|
482
|
+
project_info = issue_fields.get("project") or {}
|
|
483
|
+
project_id = project_info.get("id") or ""
|
|
484
|
+
|
|
485
|
+
issue_url = f"{self._client.url}browse/{key}" if key else self._client.url
|
|
486
|
+
|
|
487
|
+
assignee_info = issue_fields.get("assignee") or {}
|
|
488
|
+
assignee = assignee_info.get("displayName") or "None"
|
|
489
|
+
|
|
476
490
|
rel_issues = {}
|
|
477
|
-
for related_issue in issue_fields
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
491
|
+
for related_issue in issue_fields.get("issuelinks") or []:
|
|
492
|
+
rel_type = None
|
|
493
|
+
rel_key = None
|
|
494
|
+
if related_issue.get("inwardIssue"):
|
|
495
|
+
rel_type = related_issue.get("type", {}).get("inward")
|
|
496
|
+
rel_key = related_issue["inwardIssue"].get("key")
|
|
481
497
|
# rel_summary = related_issue["inwardIssue"]["fields"]["summary"]
|
|
482
|
-
|
|
483
|
-
rel_type = related_issue
|
|
484
|
-
rel_key = related_issue["outwardIssue"]
|
|
498
|
+
elif related_issue.get("outwardIssue"):
|
|
499
|
+
rel_type = related_issue.get("type", {}).get("outward")
|
|
500
|
+
rel_key = related_issue["outwardIssue"].get("key")
|
|
485
501
|
# rel_summary = related_issue["outwardIssue"]["fields"]["summary"]
|
|
486
|
-
|
|
502
|
+
|
|
503
|
+
if rel_type and rel_key:
|
|
504
|
+
rel_issues = {
|
|
505
|
+
"type": rel_type,
|
|
506
|
+
"key": rel_key,
|
|
507
|
+
"url": f"{self._client.url}browse/{rel_key}",
|
|
508
|
+
}
|
|
487
509
|
|
|
488
510
|
parsed_issue = {
|
|
489
511
|
"key": key,
|
|
490
|
-
"id":
|
|
512
|
+
"id": issue_id,
|
|
491
513
|
"projectId": project_id,
|
|
492
514
|
"summary": summary,
|
|
493
515
|
"description": description,
|
|
@@ -500,10 +522,13 @@ class JiraApiWrapper(NonCodeIndexerToolkit):
|
|
|
500
522
|
"url": issue_url,
|
|
501
523
|
"related_issues": rel_issues,
|
|
502
524
|
}
|
|
503
|
-
|
|
504
|
-
|
|
525
|
+
|
|
526
|
+
for field in (self.additional_fields or []):
|
|
527
|
+
field_value = issue_fields.get(field)
|
|
505
528
|
parsed_issue[field] = field_value
|
|
529
|
+
|
|
506
530
|
parsed.append(parsed_issue)
|
|
531
|
+
|
|
507
532
|
return parsed
|
|
508
533
|
|
|
509
534
|
@staticmethod
|
|
@@ -749,13 +774,24 @@ class JiraApiWrapper(NonCodeIndexerToolkit):
|
|
|
749
774
|
|
|
750
775
|
attachment_data = []
|
|
751
776
|
attachments = self._client.get_attachments_ids_from_issue(issue=jira_issue_key)
|
|
777
|
+
api_version = str(getattr(self._client, "api_version", "2"))
|
|
752
778
|
for attachment in attachments:
|
|
753
779
|
if attachment_pattern and not re.search(attachment_pattern, attachment['filename']):
|
|
754
780
|
logger.info(f"Skipping attachment {attachment['filename']} as it does not match pattern {attachment_pattern}")
|
|
755
781
|
continue
|
|
756
782
|
logger.info(f"Processing attachment {attachment['filename']} with ID {attachment['attachment_id']}")
|
|
757
783
|
try:
|
|
758
|
-
attachment_content =
|
|
784
|
+
attachment_content = None
|
|
785
|
+
|
|
786
|
+
# Cloud (REST v3) attachments require signed URLs returned from metadata
|
|
787
|
+
if api_version in {"3", "latest"} or self.cloud:
|
|
788
|
+
attachment_content = self._download_attachment_v3(
|
|
789
|
+
attachment['attachment_id'],
|
|
790
|
+
attachment['filename']
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
if attachment_content is None:
|
|
794
|
+
attachment_content = self._client.get_attachment_content(attachment['attachment_id'])
|
|
759
795
|
except Exception as e:
|
|
760
796
|
logger.error(
|
|
761
797
|
f"Failed to download attachment {attachment['filename']} for issue {jira_issue_key}: {str(e)}")
|
|
@@ -797,15 +833,6 @@ class JiraApiWrapper(NonCodeIndexerToolkit):
|
|
|
797
833
|
logger.debug(response_string)
|
|
798
834
|
return response_string
|
|
799
835
|
|
|
800
|
-
def _extract_attachment_content(self, attachment):
|
|
801
|
-
"""Extract attachment's content if possible (used for api v.2)"""
|
|
802
|
-
|
|
803
|
-
try:
|
|
804
|
-
content = self._client.get(attachment['content'].replace(self.base_url, ''))
|
|
805
|
-
except Exception as e:
|
|
806
|
-
content = f"Unable to parse content of '{attachment['filename']}' due to: {str(e)}"
|
|
807
|
-
return f"filename: {attachment['filename']}\ncontent: {content}"
|
|
808
|
-
|
|
809
836
|
# Helper functions for image processing
|
|
810
837
|
@staticmethod
|
|
811
838
|
def _collect_context_for_image(content: str, image_marker: str, context_radius: int = 500) -> str:
|
|
@@ -1038,6 +1065,30 @@ class JiraApiWrapper(NonCodeIndexerToolkit):
|
|
|
1038
1065
|
logger.error(f"Error downloading attachment: {str(e)}")
|
|
1039
1066
|
return None
|
|
1040
1067
|
|
|
1068
|
+
def _download_attachment_v3(self, attachment_id: str, filename: str | None = None) -> Optional[bytes]:
|
|
1069
|
+
"""Download Jira attachment using metadata content URL (required for REST v3 / Cloud)."""
|
|
1070
|
+
try:
|
|
1071
|
+
metadata = self._client.get_attachment(attachment_id)
|
|
1072
|
+
except Exception as e:
|
|
1073
|
+
logger.error(f"Failed to retrieve metadata for attachment {attachment_id}: {str(e)}")
|
|
1074
|
+
return None
|
|
1075
|
+
|
|
1076
|
+
download_url = metadata.get('content') or metadata.get('_links', {}).get('content')
|
|
1077
|
+
|
|
1078
|
+
if not download_url:
|
|
1079
|
+
logger.warning(
|
|
1080
|
+
f"Attachment {attachment_id} ({filename}) metadata does not include a content URL; falling back.")
|
|
1081
|
+
return None
|
|
1082
|
+
|
|
1083
|
+
logger.info(f"Downloading attachment {attachment_id} via metadata content URL (v3).")
|
|
1084
|
+
content = self._download_attachment(download_url)
|
|
1085
|
+
|
|
1086
|
+
if content is None:
|
|
1087
|
+
logger.error(
|
|
1088
|
+
f"Failed to download attachment {attachment_id} ({filename}) from v3 content URL: {download_url}")
|
|
1089
|
+
|
|
1090
|
+
return content
|
|
1091
|
+
|
|
1041
1092
|
def _extract_image_data(self, field_data):
|
|
1042
1093
|
"""
|
|
1043
1094
|
Extracts image data from general JSON response.
|
|
@@ -7,6 +7,7 @@ from alita_sdk.tools.base_indexer_toolkit import BaseIndexerToolkit
|
|
|
7
7
|
|
|
8
8
|
class NonCodeIndexerToolkit(BaseIndexerToolkit):
|
|
9
9
|
def _get_indexed_data(self, index_name: str):
|
|
10
|
+
self._ensure_vectorstore_initialized()
|
|
10
11
|
if not self.vector_adapter:
|
|
11
12
|
raise ToolException("Vector adapter is not initialized. "
|
|
12
13
|
"Check your configuration: embedding_model and vectorstore_type.")
|
|
@@ -37,7 +37,7 @@ class QtestToolkit(BaseToolkit):
|
|
|
37
37
|
name,
|
|
38
38
|
qtest_configuration=(QtestConfiguration, Field(description="QTest API token", json_schema_extra={
|
|
39
39
|
'configuration_types': ['qtest']})),
|
|
40
|
-
qtest_project_id=(int, Field(
|
|
40
|
+
qtest_project_id=(int, Field(description="QTest project id")),
|
|
41
41
|
no_of_tests_shown_in_dql_search=(Optional[int], Field(description="Max number of items returned by dql search",
|
|
42
42
|
default=10)),
|
|
43
43
|
|