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
|
@@ -1326,6 +1326,74 @@ class GraphQLClientWrapper(BaseModel):
|
|
|
1326
1326
|
except Exception as e:
|
|
1327
1327
|
raise ValueError(f"'{repo}' repo format is invalid. It should be like 'org-name/repo-name'. Error: {str(e)}")
|
|
1328
1328
|
|
|
1329
|
+
def _format_project_error(self, error_message: str) -> str:
|
|
1330
|
+
"""
|
|
1331
|
+
Format project access errors with user-friendly guidance.
|
|
1332
|
+
|
|
1333
|
+
Detects permission-related errors and provides actionable guidance for users
|
|
1334
|
+
to fix token permission issues.
|
|
1335
|
+
|
|
1336
|
+
Args:
|
|
1337
|
+
error_message: The original error message from get_project() or get_issue_repo()
|
|
1338
|
+
|
|
1339
|
+
Returns:
|
|
1340
|
+
str: A user-friendly error message with guidance on how to fix the issue
|
|
1341
|
+
"""
|
|
1342
|
+
# Detect permission-related errors
|
|
1343
|
+
permission_indicators = [
|
|
1344
|
+
"Resource not accessible",
|
|
1345
|
+
"INSUFFICIENT_SCOPES",
|
|
1346
|
+
"not accessible by personal access token",
|
|
1347
|
+
"requires authentication",
|
|
1348
|
+
"Bad credentials",
|
|
1349
|
+
"401",
|
|
1350
|
+
"403"
|
|
1351
|
+
]
|
|
1352
|
+
|
|
1353
|
+
is_permission_error = any(
|
|
1354
|
+
indicator.lower() in error_message.lower()
|
|
1355
|
+
for indicator in permission_indicators
|
|
1356
|
+
)
|
|
1357
|
+
|
|
1358
|
+
if is_permission_error:
|
|
1359
|
+
return (
|
|
1360
|
+
"GitHub Token Permission Error\n\n"
|
|
1361
|
+
"Your GitHub token does not have the required 'project' permission "
|
|
1362
|
+
"to access GitHub Projects (ProjectsV2).\n\n"
|
|
1363
|
+
"To fix this:\n"
|
|
1364
|
+
"1. Go to GitHub Settings > Developer settings > Personal access tokens\n"
|
|
1365
|
+
"2. Edit your token and enable the 'project' scope (read/write access to projects)\n"
|
|
1366
|
+
"3. Update your toolkit configuration with the new token\n\n"
|
|
1367
|
+
f"Technical details: {error_message}"
|
|
1368
|
+
)
|
|
1369
|
+
|
|
1370
|
+
# For other errors (not found, network issues, etc.), return with clearer context
|
|
1371
|
+
if "not found" in error_message.lower():
|
|
1372
|
+
return f"Project not found. Please verify the project title exists and is accessible. {error_message}"
|
|
1373
|
+
|
|
1374
|
+
if "No repository data found" in error_message:
|
|
1375
|
+
return (
|
|
1376
|
+
"Repository not found or not accessible. Please verify:\n"
|
|
1377
|
+
"1. The repository name is correct (format: owner/repo-name)\n"
|
|
1378
|
+
"2. Your token has access to this repository\n\n"
|
|
1379
|
+
f"Technical details: {error_message}"
|
|
1380
|
+
)
|
|
1381
|
+
|
|
1382
|
+
return f"Failed to access GitHub project. {error_message}"
|
|
1383
|
+
|
|
1384
|
+
def _format_repo_error(self, error_message: str) -> str:
|
|
1385
|
+
"""
|
|
1386
|
+
Format repository access errors with user-friendly guidance.
|
|
1387
|
+
|
|
1388
|
+
Args:
|
|
1389
|
+
error_message: The original error message from get_issue_repo()
|
|
1390
|
+
|
|
1391
|
+
Returns:
|
|
1392
|
+
str: A user-friendly error message with guidance
|
|
1393
|
+
"""
|
|
1394
|
+
# Reuse the project error formatting logic as the errors are similar
|
|
1395
|
+
return self._format_project_error(error_message)
|
|
1396
|
+
|
|
1329
1397
|
def _get_repo_extra_info(self, repository: Dict[str, Any]) -> Tuple[str, List[Dict[str, Any]], List[Dict[str, Any]]]:
|
|
1330
1398
|
"""Helper to extract repository ID, labels and assignable users of the repository."""
|
|
1331
1399
|
repository_id = repository.get("repositoryId")
|
|
@@ -1356,22 +1424,31 @@ class GraphQLClientWrapper(BaseModel):
|
|
|
1356
1424
|
except ValueError as e:
|
|
1357
1425
|
return str(e)
|
|
1358
1426
|
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1427
|
+
# Get project data with type safety check
|
|
1428
|
+
result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
|
|
1429
|
+
|
|
1430
|
+
# Type check: get_project() returns str on error, dict on success
|
|
1431
|
+
if isinstance(result, str):
|
|
1432
|
+
return self._format_project_error(result)
|
|
1433
|
+
|
|
1434
|
+
project = result.get("project")
|
|
1435
|
+
project_id = result.get("projectId")
|
|
1436
|
+
|
|
1437
|
+
if issue_repo:
|
|
1438
|
+
try:
|
|
1439
|
+
issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
|
|
1440
|
+
except ValueError as e:
|
|
1441
|
+
return str(e)
|
|
1442
|
+
|
|
1443
|
+
issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
|
|
1444
|
+
|
|
1445
|
+
# Type check: get_issue_repo() returns str on error, dict on success
|
|
1446
|
+
if isinstance(issue_repo_result, str):
|
|
1447
|
+
return self._format_repo_error(issue_repo_result)
|
|
1448
|
+
|
|
1449
|
+
repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
|
|
1450
|
+
else:
|
|
1451
|
+
repository_id, labels, assignable_users = self._get_repo_extra_info(result)
|
|
1375
1452
|
|
|
1376
1453
|
missing_fields = []
|
|
1377
1454
|
updated_fields = []
|
|
@@ -1444,26 +1521,35 @@ class GraphQLClientWrapper(BaseModel):
|
|
|
1444
1521
|
except Exception as e:
|
|
1445
1522
|
return str(e)
|
|
1446
1523
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1524
|
+
# Get project data with type safety check
|
|
1525
|
+
result = self.get_project(owner=owner_name, repo_name=repo_name, project_title=project_title)
|
|
1526
|
+
|
|
1527
|
+
# Type check: get_project() returns str on error, dict on success
|
|
1528
|
+
if isinstance(result, str):
|
|
1529
|
+
return self._format_project_error(result)
|
|
1530
|
+
|
|
1531
|
+
project = result.get("project")
|
|
1532
|
+
project_id = result.get("projectId")
|
|
1533
|
+
|
|
1534
|
+
if issue_repo:
|
|
1535
|
+
try:
|
|
1536
|
+
issue_owner_name, issue_repo_name = self._parse_repo(issue_repo)
|
|
1537
|
+
except ValueError as e:
|
|
1538
|
+
return str(e)
|
|
1539
|
+
|
|
1540
|
+
issue_repo_result = self.get_issue_repo(owner=issue_owner_name, repo_name=issue_repo_name)
|
|
1541
|
+
|
|
1542
|
+
# Type check: get_issue_repo() returns str on error, dict on success
|
|
1543
|
+
if isinstance(issue_repo_result, str):
|
|
1544
|
+
return self._format_repo_error(issue_repo_result)
|
|
1545
|
+
|
|
1546
|
+
repository_id, labels, assignable_users = self._get_repo_extra_info(issue_repo_result)
|
|
1547
|
+
else:
|
|
1548
|
+
repository_id, labels, assignable_users = self._get_repo_extra_info(result)
|
|
1464
1549
|
|
|
1465
1550
|
missing_fields = []
|
|
1466
1551
|
fields_to_update = []
|
|
1552
|
+
updated_fields = []
|
|
1467
1553
|
|
|
1468
1554
|
if fields:
|
|
1469
1555
|
try:
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from typing import Dict, List, Optional, Any
|
|
2
2
|
from pydantic import BaseModel, Field, SecretStr, create_model
|
|
3
3
|
|
|
4
|
+
from alita_sdk.tools.utils.tool_prompts import UPDATE_FILE_PROMPT_WITH_PATH
|
|
5
|
+
|
|
6
|
+
|
|
4
7
|
# Base schemas for GitHub API wrapper
|
|
5
8
|
class GitHubAuthConfig(BaseModel):
|
|
6
9
|
github_access_token: Optional[SecretStr] = None
|
|
@@ -28,6 +31,12 @@ CreateBranchName = create_model(
|
|
|
28
31
|
proposed_branch_name=(str, Field(description="The name of the new branch to create, e.g. `feature-branch`"))
|
|
29
32
|
)
|
|
30
33
|
|
|
34
|
+
DeleteBranchName = create_model(
|
|
35
|
+
"DeleteBranchName",
|
|
36
|
+
branch_name=(str, Field(description="The name of the branch to delete, e.g. `feature-branch`")),
|
|
37
|
+
force=(Optional[bool], Field(default=False, description="Force deletion even if branch is the current active branch"))
|
|
38
|
+
)
|
|
39
|
+
|
|
31
40
|
DirectoryPath = create_model(
|
|
32
41
|
"DirectoryPath",
|
|
33
42
|
directory_path=(str, Field(description="The path of the directory, e.g. `src/my_dir`"))
|
|
@@ -42,7 +51,7 @@ ReadFile = create_model(
|
|
|
42
51
|
|
|
43
52
|
UpdateFile = create_model(
|
|
44
53
|
"UpdateFile",
|
|
45
|
-
file_query=(str, Field(description=
|
|
54
|
+
file_query=(str, Field(description=UPDATE_FILE_PROMPT_WITH_PATH)),
|
|
46
55
|
repo_name=(Optional[str], Field(default=None, description="Name of the repository (e.g., 'owner/repo'). If None, uses the default repository.")),
|
|
47
56
|
commit_message=(Optional[str], Field(default=None, description="Commit message for the update operation")),
|
|
48
57
|
)
|
|
@@ -92,7 +101,7 @@ SearchIssues = create_model(
|
|
|
92
101
|
"SearchIssues",
|
|
93
102
|
search_query=(str, Field(description="Keywords or query for searching issues and PRs in Github")),
|
|
94
103
|
repo_name=(Optional[str], Field(description="Name of the repository to search issues in", default=None)),
|
|
95
|
-
max_count=(Optional[int], Field(description="Maximum number of issues to return", default=30))
|
|
104
|
+
max_count=(Optional[int], Field(description="Maximum number of issues to return", default=30, gt=0))
|
|
96
105
|
)
|
|
97
106
|
|
|
98
107
|
CreateIssue = create_model(
|
|
@@ -152,7 +161,7 @@ GetCommits = create_model(
|
|
|
152
161
|
since=(Optional[str], Field(description="Only commits after this date will be returned (ISO format)", default=None)),
|
|
153
162
|
until=(Optional[str], Field(description="Only commits before this date will be returned (ISO format)", default=None)),
|
|
154
163
|
author=(Optional[str], Field(description="The author of the commits", default=None)),
|
|
155
|
-
max_count=(Optional[int], Field(description="Maximum number of commits to return (default: 30)", default=30))
|
|
164
|
+
max_count=(Optional[int], Field(description="Maximum number of commits to return (default: 30)", default=30, gt=0))
|
|
156
165
|
)
|
|
157
166
|
|
|
158
167
|
GetCommitChanges = create_model(
|
|
@@ -213,7 +222,7 @@ ListProjectIssues = create_model(
|
|
|
213
222
|
"ListProjectIssues",
|
|
214
223
|
board_repo=(str, Field(description="The organization and repository for the board (project). Example: 'org-name/repo-name'")),
|
|
215
224
|
project_number=(int, Field(description="The project number as shown in the project URL")),
|
|
216
|
-
items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100))
|
|
225
|
+
items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100, gt=0))
|
|
217
226
|
)
|
|
218
227
|
|
|
219
228
|
SearchProjectIssues = create_model(
|
|
@@ -221,7 +230,7 @@ SearchProjectIssues = create_model(
|
|
|
221
230
|
board_repo=(str, Field(description="The organization and repository for the board (project). Example: 'org-name/repo-name'")),
|
|
222
231
|
project_number=(int, Field(description="The project number as shown in the project URL")),
|
|
223
232
|
search_query=(str, Field(description="Search query for filtering issues. Examples: 'status:In Progress', 'release:v1.0'")),
|
|
224
|
-
items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100))
|
|
233
|
+
items_count=(Optional[int], Field(description="Maximum number of items to retrieve", default=100, gt=0))
|
|
225
234
|
)
|
|
226
235
|
|
|
227
236
|
ListProjectViews = create_model(
|
alita_sdk/tools/github/tool.py
CHANGED
|
@@ -29,6 +29,10 @@ class GitHubAction(BaseTool):
|
|
|
29
29
|
) -> str:
|
|
30
30
|
"""Use the GitHub API to run an operation."""
|
|
31
31
|
try:
|
|
32
|
-
|
|
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
|
+
mode = re.sub(r'_\d+$', '', self.mode) if self.mode else self.mode
|
|
36
|
+
return self.api_wrapper.run(mode, *args, **kwargs)
|
|
33
37
|
except Exception as e:
|
|
34
38
|
return f"Error: {format_exc()}"
|
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
CREATE_FILE_PROMPT = """Create new file in your github repository."""
|
|
2
2
|
|
|
3
|
-
UPDATE_FILE_PROMPT = """Updates the contents of a file in repository. Input MUST strictly follow these rules:
|
|
4
|
-
Specify the file to modify by passing a full file path (the path must not start with a slash); Specify at lest 2 lines of the old contents which you would like to replace wrapped in OLD <<<< and >>>> OLD; Specify the new contents which you would like to replace the old contents with wrapped in NEW <<<< and >>>> NEW; NEW content may contain lines from OLD content in case you want to add content without removing the old content
|
|
5
3
|
|
|
6
|
-
|
|
4
|
+
DELETE_BRANCH_PROMPT = """Delete a branch from the GitHub repository.
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
IMPORTANT: This tool will NOT delete protected branches:
|
|
7
|
+
- 'main' and 'master' branches are always protected
|
|
8
|
+
- The configured base branch is protected
|
|
9
|
+
- The currently active branch is protected (unless force=True)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
>>>> OLD
|
|
14
|
-
NEW <<<<
|
|
15
|
-
new contents
|
|
16
|
-
>>>> NEW
|
|
11
|
+
Parameters:
|
|
12
|
+
- branch_name: The name of the branch to delete (e.g., 'feature-branch')
|
|
13
|
+
- force: Set to True to delete even if it's the current active branch (default: False)
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
test/test.txt
|
|
21
|
-
|
|
22
|
-
OLD <<<<
|
|
23
|
-
existing contents
|
|
24
|
-
>>>> OLD
|
|
25
|
-
NEW <<<<
|
|
26
|
-
existing contents
|
|
27
|
-
new contents
|
|
28
|
-
>>>> NEW"""
|
|
15
|
+
Returns a success or error message."""
|
|
29
16
|
|
|
30
17
|
CREATE_ISSUE_PROMPT = """
|
|
31
18
|
Tool allows to create a new issue in a GitHub repository.
|
|
@@ -8,14 +8,15 @@ from pydantic.fields import Field
|
|
|
8
8
|
|
|
9
9
|
from .api_wrapper import GitLabAPIWrapper
|
|
10
10
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
11
|
-
from ..utils import clean_string,
|
|
11
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
12
12
|
from ...configurations.gitlab import GitlabConfiguration
|
|
13
13
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
14
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
14
15
|
|
|
15
16
|
name = "gitlab"
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def
|
|
19
|
+
def get_toolkit(tool):
|
|
19
20
|
return AlitaGitlabToolkit().get_toolkit(
|
|
20
21
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
21
22
|
repository=tool['settings']['repository'],
|
|
@@ -30,17 +31,18 @@ def get_tools(tool):
|
|
|
30
31
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
31
32
|
vectorstore_type="PGVector",
|
|
32
33
|
toolkit_name=tool.get('toolkit_name')
|
|
33
|
-
)
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def get_tools(tool):
|
|
37
|
+
return get_toolkit(tool).get_tools()
|
|
34
38
|
|
|
35
39
|
class AlitaGitlabToolkit(BaseToolkit):
|
|
36
40
|
tools: List[BaseTool] = []
|
|
37
|
-
toolkit_max_length: int = 0
|
|
38
41
|
|
|
39
42
|
@staticmethod
|
|
40
43
|
def toolkit_config_schema() -> BaseModel:
|
|
41
44
|
selected_tools = {x['name']: x['args_schema'].schema() for x in
|
|
42
45
|
GitLabAPIWrapper.model_construct().get_available_tools()}
|
|
43
|
-
AlitaGitlabToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
44
46
|
return create_model(
|
|
45
47
|
name,
|
|
46
48
|
repository=(str, Field(description="GitLab repository")),
|
|
@@ -57,7 +59,6 @@ class AlitaGitlabToolkit(BaseToolkit):
|
|
|
57
59
|
'metadata': {
|
|
58
60
|
"label": "GitLab",
|
|
59
61
|
"icon_url": None,
|
|
60
|
-
"max_length": AlitaGitlabToolkit.toolkit_max_length,
|
|
61
62
|
"categories": ["code repositories"],
|
|
62
63
|
"extra_categories": ["gitlab", "git", "repository", "code", "version control"],
|
|
63
64
|
}
|
|
@@ -77,19 +78,22 @@ class AlitaGitlabToolkit(BaseToolkit):
|
|
|
77
78
|
**(kwargs.get('embedding_configuration') or {}),
|
|
78
79
|
}
|
|
79
80
|
gitlab_api_wrapper = GitLabAPIWrapper(**wrapper_payload)
|
|
80
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
81
81
|
available_tools: List[Dict] = gitlab_api_wrapper.get_available_tools()
|
|
82
82
|
tools = []
|
|
83
83
|
for tool in available_tools:
|
|
84
84
|
if selected_tools:
|
|
85
85
|
if tool["name"] not in selected_tools:
|
|
86
86
|
continue
|
|
87
|
-
|
|
87
|
+
description = tool["description"] + f"\nrepo: {gitlab_api_wrapper.repository}"
|
|
88
|
+
if toolkit_name:
|
|
89
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
90
|
+
description = description[:1000]
|
|
88
91
|
tools.append(BaseAction(
|
|
89
92
|
api_wrapper=gitlab_api_wrapper,
|
|
90
|
-
name=
|
|
91
|
-
description=
|
|
92
|
-
args_schema=tool["args_schema"]
|
|
93
|
+
name=tool["name"],
|
|
94
|
+
description=description,
|
|
95
|
+
args_schema=tool["args_schema"],
|
|
96
|
+
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
97
|
))
|
|
94
98
|
return cls(tools=tools)
|
|
95
99
|
|