alita-sdk 0.3.379__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/__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 +156 -0
- alita_sdk/cli/agent_loader.py +245 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3113 -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 +1073 -0
- alita_sdk/cli/mcp_loader.py +315 -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 +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 +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 +94 -2
- alita_sdk/configurations/confluence.py +130 -1
- alita_sdk/configurations/figma.py +76 -0
- alita_sdk/configurations/gitlab.py +91 -0
- alita_sdk/configurations/jira.py +103 -0
- 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/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 +3 -3
- alita_sdk/runtime/clients/client.py +388 -46
- 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 +8 -21
- alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
- alita_sdk/runtime/langchain/assistant.py +157 -39
- alita_sdk/runtime/langchain/constants.py +647 -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/AlitaJSONLinesLoader.py +77 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -4
- 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 +40 -19
- alita_sdk/runtime/langchain/langraph_agent.py +405 -84
- alita_sdk/runtime/langchain/utils.py +106 -7
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- 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 +31 -0
- alita_sdk/runtime/toolkits/application.py +29 -10
- alita_sdk/runtime/toolkits/artifact.py +20 -11
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +783 -0
- 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 +356 -69
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/__init__.py +10 -3
- alita_sdk/runtime/tools/application.py +27 -6
- alita_sdk/runtime/tools/artifact.py +511 -28
- alita_sdk/runtime/tools/data_analysis.py +183 -0
- alita_sdk/runtime/tools/function.py +67 -35
- alita_sdk/runtime/tools/graph.py +10 -4
- alita_sdk/runtime/tools/image_generation.py +148 -46
- alita_sdk/runtime/tools/llm.py +1003 -128
- alita_sdk/runtime/tools/loop.py +3 -1
- alita_sdk/runtime/tools/loop_output.py +3 -1
- 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 +8 -5
- 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 +65 -48
- alita_sdk/runtime/tools/skill_router.py +776 -0
- alita_sdk/runtime/tools/tool.py +3 -1
- alita_sdk/runtime/tools/vectorstore.py +9 -3
- alita_sdk/runtime/tools/vectorstore_base.py +70 -14
- 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 +361 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/serialization.py +155 -0
- alita_sdk/runtime/utils/streamlit.py +40 -13
- alita_sdk/runtime/utils/toolkit_utils.py +30 -9
- alita_sdk/runtime/utils/utils.py +36 -0
- alita_sdk/tools/__init__.py +134 -35
- alita_sdk/tools/ado/repos/__init__.py +51 -32
- 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 -12
- alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
- alita_sdk/tools/ado/work_item/__init__.py +26 -13
- alita_sdk/tools/ado/work_item/ado_wrapper.py +73 -11
- 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 +271 -84
- alita_sdk/tools/bitbucket/__init__.py +17 -11
- 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/sematic/proposal_chunker.py +1 -1
- 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 +11 -8
- alita_sdk/tools/code_indexer_toolkit.py +82 -22
- alita_sdk/tools/confluence/__init__.py +22 -16
- alita_sdk/tools/confluence/api_wrapper.py +107 -30
- alita_sdk/tools/confluence/loader.py +14 -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 +14 -15
- 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 +16 -11
- alita_sdk/tools/gitlab/api_wrapper.py +218 -48
- alita_sdk/tools/gitlab_org/__init__.py +10 -9
- 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 +11 -8
- alita_sdk/tools/google_places/api_wrapper.py +1 -1
- alita_sdk/tools/jira/__init__.py +17 -10
- alita_sdk/tools/jira/api_wrapper.py +92 -41
- 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 +12 -4
- alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
- alita_sdk/tools/ocr/__init__.py +11 -8
- alita_sdk/tools/openapi/__init__.py +491 -106
- 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 +10 -9
- alita_sdk/tools/pptx/__init__.py +11 -10
- alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
- alita_sdk/tools/qtest/__init__.py +31 -11
- alita_sdk/tools/qtest/api_wrapper.py +2135 -86
- alita_sdk/tools/rally/__init__.py +10 -9
- alita_sdk/tools/rally/api_wrapper.py +1 -1
- alita_sdk/tools/report_portal/__init__.py +12 -8
- alita_sdk/tools/salesforce/__init__.py +10 -8
- alita_sdk/tools/servicenow/__init__.py +17 -15
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +10 -7
- alita_sdk/tools/sharepoint/api_wrapper.py +129 -38
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +10 -7
- alita_sdk/tools/slack/api_wrapper.py +2 -2
- alita_sdk/tools/sql/__init__.py +12 -9
- alita_sdk/tools/testio/__init__.py +10 -7
- alita_sdk/tools/testrail/__init__.py +11 -10
- alita_sdk/tools/testrail/api_wrapper.py +1 -1
- alita_sdk/tools/utils/__init__.py +9 -4
- alita_sdk/tools/utils/content_parser.py +103 -18
- 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 +30 -13
- alita_sdk/tools/xray/__init__.py +13 -9
- alita_sdk/tools/yagmail/__init__.py +9 -3
- alita_sdk/tools/zephyr/__init__.py +10 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +11 -7
- alita_sdk/tools/zephyr_essential/__init__.py +10 -7
- 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 -8
- alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
- alita_sdk/tools/zephyr_squad/__init__.py +10 -7
- {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +154 -8
- 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.379.dist-info/RECORD +0 -360
- {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Data Analysis internal tool for Alita SDK.
|
|
3
|
+
|
|
4
|
+
This tool provides Pandas-based data analysis capabilities as an internal tool,
|
|
5
|
+
accessible through the "Enable internal tools" dropdown menu.
|
|
6
|
+
|
|
7
|
+
It uses the conversation attachment bucket for file storage, providing seamless
|
|
8
|
+
integration with drag-and-drop file uploads in chat.
|
|
9
|
+
"""
|
|
10
|
+
import logging
|
|
11
|
+
from typing import Any, List, Literal, Optional, Type
|
|
12
|
+
|
|
13
|
+
from langchain_core.tools import BaseTool, BaseToolkit
|
|
14
|
+
from pydantic import BaseModel, ConfigDict, create_model, Field
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
name = "data_analysis"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_tools(tools_list: list, alita_client=None, llm=None, memory_store=None):
|
|
22
|
+
"""
|
|
23
|
+
Get data analysis tools for the provided tool configurations.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
tools_list: List of tool configurations
|
|
27
|
+
alita_client: Alita client instance (required for data analysis)
|
|
28
|
+
llm: LLM client instance (required for code generation)
|
|
29
|
+
memory_store: Optional memory store instance (unused)
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
List of data analysis tools
|
|
33
|
+
"""
|
|
34
|
+
all_tools = []
|
|
35
|
+
|
|
36
|
+
for tool in tools_list:
|
|
37
|
+
if (tool.get('type') == 'data_analysis' or
|
|
38
|
+
tool.get('toolkit_name') == 'data_analysis'):
|
|
39
|
+
try:
|
|
40
|
+
if not alita_client:
|
|
41
|
+
logger.error("Alita client is required for data analysis tools")
|
|
42
|
+
continue
|
|
43
|
+
|
|
44
|
+
settings = tool.get('settings', {})
|
|
45
|
+
bucket_name = settings.get('bucket_name')
|
|
46
|
+
|
|
47
|
+
if not bucket_name:
|
|
48
|
+
logger.error("bucket_name is required for data analysis tools")
|
|
49
|
+
continue
|
|
50
|
+
|
|
51
|
+
toolkit_instance = DataAnalysisToolkit.get_toolkit(
|
|
52
|
+
alita_client=alita_client,
|
|
53
|
+
llm=llm,
|
|
54
|
+
bucket_name=bucket_name,
|
|
55
|
+
toolkit_name=tool.get('toolkit_name', '')
|
|
56
|
+
)
|
|
57
|
+
all_tools.extend(toolkit_instance.get_tools())
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.error(f"Error in data analysis toolkit get_tools: {e}")
|
|
60
|
+
logger.error(f"Tool config: {tool}")
|
|
61
|
+
raise
|
|
62
|
+
|
|
63
|
+
return all_tools
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class DataAnalysisToolkit(BaseToolkit):
|
|
67
|
+
"""
|
|
68
|
+
Data Analysis toolkit providing Pandas-based data analysis capabilities.
|
|
69
|
+
|
|
70
|
+
This is an internal tool that uses the conversation attachment bucket
|
|
71
|
+
for file storage, enabling seamless integration with chat file uploads.
|
|
72
|
+
"""
|
|
73
|
+
tools: List[BaseTool] = []
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def toolkit_config_schema() -> Type[BaseModel]:
|
|
77
|
+
"""Get the configuration schema for the data analysis toolkit."""
|
|
78
|
+
# Import PandasWrapper to get available tools schema
|
|
79
|
+
from alita_sdk.tools.pandas.api_wrapper import PandasWrapper
|
|
80
|
+
|
|
81
|
+
selected_tools = {
|
|
82
|
+
x['name']: x['args_schema'].model_json_schema()
|
|
83
|
+
for x in PandasWrapper.model_construct().get_available_tools()
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return create_model(
|
|
87
|
+
'data_analysis',
|
|
88
|
+
bucket_name=(
|
|
89
|
+
Optional[str],
|
|
90
|
+
Field(
|
|
91
|
+
default=None,
|
|
92
|
+
title="Bucket name",
|
|
93
|
+
description="Bucket where files are stored (auto-injected from conversation)"
|
|
94
|
+
)
|
|
95
|
+
),
|
|
96
|
+
selected_tools=(
|
|
97
|
+
List[Literal[tuple(selected_tools)]],
|
|
98
|
+
Field(
|
|
99
|
+
default=[],
|
|
100
|
+
json_schema_extra={'args_schemas': selected_tools}
|
|
101
|
+
)
|
|
102
|
+
),
|
|
103
|
+
__config__=ConfigDict(json_schema_extra={
|
|
104
|
+
'metadata': {
|
|
105
|
+
"label": "Data Analysis",
|
|
106
|
+
"icon_url": "data-analysis.svg",
|
|
107
|
+
"hidden": True, # Hidden from regular toolkit menu
|
|
108
|
+
"categories": ["internal_tool"],
|
|
109
|
+
"extra_categories": ["data analysis", "pandas", "dataframes", "data science"],
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def get_toolkit(
|
|
116
|
+
cls,
|
|
117
|
+
alita_client=None,
|
|
118
|
+
llm=None,
|
|
119
|
+
bucket_name: str = None,
|
|
120
|
+
toolkit_name: Optional[str] = None,
|
|
121
|
+
selected_tools: Optional[List[str]] = None,
|
|
122
|
+
**kwargs
|
|
123
|
+
):
|
|
124
|
+
"""
|
|
125
|
+
Get toolkit with data analysis tools.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
alita_client: Alita client instance (required)
|
|
129
|
+
llm: LLM for code generation (optional, uses alita_client.llm if not provided)
|
|
130
|
+
bucket_name: Conversation attachment bucket (required)
|
|
131
|
+
toolkit_name: Optional name prefix for tools
|
|
132
|
+
selected_tools: Optional list of tool names to include (default: all)
|
|
133
|
+
**kwargs: Additional arguments
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
DataAnalysisToolkit instance with configured tools
|
|
137
|
+
|
|
138
|
+
Raises:
|
|
139
|
+
ValueError: If alita_client or bucket_name is not provided
|
|
140
|
+
"""
|
|
141
|
+
if not alita_client:
|
|
142
|
+
raise ValueError("Alita client is required for data analysis")
|
|
143
|
+
|
|
144
|
+
if not bucket_name:
|
|
145
|
+
raise ValueError("bucket_name is required for data analysis (should be conversation attachment bucket)")
|
|
146
|
+
|
|
147
|
+
# Import the PandasWrapper from existing toolkit
|
|
148
|
+
from alita_sdk.tools.pandas.api_wrapper import PandasWrapper
|
|
149
|
+
from alita_sdk.tools.base.tool import BaseAction
|
|
150
|
+
|
|
151
|
+
# Create wrapper with conversation bucket
|
|
152
|
+
wrapper = PandasWrapper(
|
|
153
|
+
alita=alita_client,
|
|
154
|
+
llm=llm,
|
|
155
|
+
bucket_name=bucket_name
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Get tools from wrapper
|
|
159
|
+
available_tools = wrapper.get_available_tools()
|
|
160
|
+
tools = []
|
|
161
|
+
|
|
162
|
+
for tool in available_tools:
|
|
163
|
+
# Filter by selected_tools if provided
|
|
164
|
+
if selected_tools and tool["name"] not in selected_tools:
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
description = tool["description"]
|
|
168
|
+
if toolkit_name:
|
|
169
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
170
|
+
description = description[:1000]
|
|
171
|
+
|
|
172
|
+
tools.append(BaseAction(
|
|
173
|
+
api_wrapper=wrapper,
|
|
174
|
+
name=tool["name"],
|
|
175
|
+
description=description,
|
|
176
|
+
args_schema=tool["args_schema"],
|
|
177
|
+
metadata={"toolkit_name": toolkit_name, "toolkit_type": name} if toolkit_name else {}
|
|
178
|
+
))
|
|
179
|
+
|
|
180
|
+
return cls(tools=tools)
|
|
181
|
+
|
|
182
|
+
def get_tools(self):
|
|
183
|
+
return self.tools
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import base64
|
|
1
2
|
import json
|
|
2
3
|
import logging
|
|
3
4
|
from copy import deepcopy
|
|
@@ -7,15 +8,28 @@ from langchain_core.callbacks import dispatch_custom_event
|
|
|
7
8
|
from langchain_core.messages import ToolCall
|
|
8
9
|
from langchain_core.runnables import RunnableConfig
|
|
9
10
|
from langchain_core.tools import BaseTool, ToolException
|
|
10
|
-
from typing import Any, Optional, Union
|
|
11
|
+
from typing import Any, Optional, Union
|
|
11
12
|
from langchain_core.utils.function_calling import convert_to_openai_tool
|
|
12
13
|
from pydantic import ValidationError
|
|
13
14
|
|
|
14
15
|
from ..langchain.utils import propagate_the_input_mapping
|
|
16
|
+
from ..utils.serialization import safe_serialize
|
|
15
17
|
|
|
16
18
|
logger = logging.getLogger(__name__)
|
|
17
19
|
|
|
18
20
|
|
|
21
|
+
def replace_escaped_newlines(data):
|
|
22
|
+
"""
|
|
23
|
+
Replace \\n with \n in all string values recursively.
|
|
24
|
+
Required for sanitization of state variables in code node
|
|
25
|
+
"""
|
|
26
|
+
if isinstance(data, dict):
|
|
27
|
+
return {key: replace_escaped_newlines(value) for key, value in data.items()}
|
|
28
|
+
elif isinstance(data, str):
|
|
29
|
+
return data.replace('\\n', '\n')
|
|
30
|
+
else:
|
|
31
|
+
return data
|
|
32
|
+
|
|
19
33
|
class FunctionTool(BaseTool):
|
|
20
34
|
name: str = 'FunctionalTool'
|
|
21
35
|
description: str = 'This is direct call node for tools'
|
|
@@ -28,31 +42,36 @@ class FunctionTool(BaseTool):
|
|
|
28
42
|
alita_client: Optional[Any] = None
|
|
29
43
|
|
|
30
44
|
def _prepare_pyodide_input(self, state: Union[str, dict, ToolCall]) -> str:
|
|
31
|
-
"""Prepare input for PyodideSandboxTool by injecting state into the code block.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
"""Prepare input for PyodideSandboxTool by injecting state into the code block.
|
|
46
|
+
|
|
47
|
+
Uses base64 encoding to avoid string escaping issues when passing JSON
|
|
48
|
+
through multiple layers of parsing (Python -> Deno -> Pyodide) and compression to minimize args list
|
|
49
|
+
"""
|
|
50
|
+
import base64
|
|
51
|
+
import zlib
|
|
52
|
+
|
|
53
|
+
state_copy = replace_escaped_newlines(deepcopy(state))
|
|
54
|
+
if 'messages' in state_copy:
|
|
55
|
+
del state_copy['messages']
|
|
56
|
+
|
|
57
|
+
# Use safe_serialize to handle Pydantic models, datetime, and other non-JSON types
|
|
58
|
+
state_json = safe_serialize(state_copy)
|
|
59
|
+
|
|
60
|
+
# Use base64 encoding to avoid all string escaping issues
|
|
61
|
+
# This is more robust than repr() when the code passes through multiple parsers
|
|
62
|
+
# use compression to avoid issue with `{"error": "Error executing code: [Errno 7] Argument list too long: 'deno'"}`
|
|
63
|
+
compressed = zlib.compress(state_json.encode('utf-8'))
|
|
64
|
+
encoded = base64.b64encode(compressed).decode('ascii')
|
|
65
|
+
|
|
66
|
+
pyodide_predata = f'''#state dict
|
|
67
|
+
import json
|
|
68
|
+
import base64
|
|
69
|
+
import zlib
|
|
70
|
+
|
|
71
|
+
compressed_state = base64.b64decode('{encoded}')
|
|
72
|
+
state_json = zlib.decompress(compressed_state).decode('utf-8')
|
|
73
|
+
alita_state = json.loads(state_json)
|
|
74
|
+
'''
|
|
56
75
|
return pyodide_predata
|
|
57
76
|
|
|
58
77
|
def _handle_pyodide_output(self, tool_result: Any) -> dict:
|
|
@@ -111,7 +130,8 @@ class FunctionTool(BaseTool):
|
|
|
111
130
|
|
|
112
131
|
# special handler for PyodideSandboxTool
|
|
113
132
|
if self._is_pyodide_tool():
|
|
114
|
-
|
|
133
|
+
# replace new lines in strings in code block
|
|
134
|
+
code = func_args['code'].replace('\\n', '\\\\n')
|
|
115
135
|
func_args['code'] = f"{self._prepare_pyodide_input(state)}\n{code}"
|
|
116
136
|
try:
|
|
117
137
|
tool_result = self.tool.invoke(func_args, config, **kwargs)
|
|
@@ -132,14 +152,26 @@ class FunctionTool(BaseTool):
|
|
|
132
152
|
if not self.output_variables:
|
|
133
153
|
return {"messages": [{"role": "assistant", "content": dumps(tool_result)}]}
|
|
134
154
|
else:
|
|
135
|
-
if self.output_variables
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
155
|
+
if "messages" in self.output_variables:
|
|
156
|
+
if 'messages' in tool_result:
|
|
157
|
+
# case when the sub-graph has been executed
|
|
158
|
+
messages_dict = {"messages": tool_result['messages']}
|
|
159
|
+
else:
|
|
160
|
+
messages_dict = {
|
|
161
|
+
"messages": [{
|
|
162
|
+
"role": "assistant",
|
|
163
|
+
"content": dumps(tool_result)
|
|
164
|
+
if not isinstance(tool_result, ToolException) and not isinstance(tool_result, str)
|
|
165
|
+
else str(tool_result)
|
|
166
|
+
}]
|
|
167
|
+
}
|
|
168
|
+
for var in self.output_variables:
|
|
169
|
+
if var != "messages":
|
|
170
|
+
if isinstance(tool_result, dict) and var in tool_result:
|
|
171
|
+
messages_dict[var] = tool_result[var]
|
|
172
|
+
else:
|
|
173
|
+
messages_dict[var] = tool_result
|
|
174
|
+
return messages_dict
|
|
143
175
|
else:
|
|
144
176
|
return { self.output_variables[0]: tool_result }
|
|
145
177
|
except ValidationError:
|
alita_sdk/runtime/tools/graph.py
CHANGED
|
@@ -47,8 +47,8 @@ def formulate_query(kwargs):
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class GraphTool(BaseTool):
|
|
50
|
-
name: str
|
|
51
|
-
description: str
|
|
50
|
+
name: str = 'GraphTool'
|
|
51
|
+
description: str = 'Graph tool for tools'
|
|
52
52
|
graph: CompiledStateGraph
|
|
53
53
|
args_schema: Type[BaseModel] = graphToolSchema
|
|
54
54
|
return_type: str = "str"
|
|
@@ -65,10 +65,16 @@ class GraphTool(BaseTool):
|
|
|
65
65
|
all_kwargs = {**kwargs, **extras, **schema_values}
|
|
66
66
|
if config is None:
|
|
67
67
|
config = {}
|
|
68
|
-
|
|
68
|
+
# Pass the config to the _run empty or the one passed from the parent executor.
|
|
69
|
+
return self._run(config, **all_kwargs)
|
|
69
70
|
|
|
70
71
|
def _run(self, *args, **kwargs):
|
|
71
|
-
|
|
72
|
+
config = None
|
|
73
|
+
# From invoke method we are passing only 1 arg so it is safe to do this condition and config assignment.
|
|
74
|
+
# Default to None is safe because it will be checked also on the langchain side.
|
|
75
|
+
if args:
|
|
76
|
+
config = args[0]
|
|
77
|
+
response = self.graph.invoke(formulate_query(kwargs), config=config)
|
|
72
78
|
if self.return_type == "str":
|
|
73
79
|
return response["output"]
|
|
74
80
|
else:
|
|
@@ -1,17 +1,62 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Image generation tool for Alita SDK.
|
|
3
3
|
"""
|
|
4
|
+
import json
|
|
4
5
|
import logging
|
|
5
|
-
|
|
6
|
-
from
|
|
7
|
-
from
|
|
6
|
+
import uuid
|
|
7
|
+
from typing import Optional, Type, Any, List, Literal
|
|
8
|
+
from langchain_core.tools import BaseTool, BaseToolkit
|
|
9
|
+
from pydantic import BaseModel, Field, create_model, ConfigDict
|
|
8
10
|
|
|
9
11
|
logger = logging.getLogger(__name__)
|
|
10
12
|
|
|
13
|
+
name = "image_generation"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_tools(tools_list: list, alita_client=None, llm=None,
|
|
17
|
+
memory_store=None):
|
|
18
|
+
"""
|
|
19
|
+
Get image generation tools for the provided tool configurations.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
tools_list: List of tool configurations
|
|
23
|
+
alita_client: Alita client instance (required for image generation)
|
|
24
|
+
llm: LLM client instance (unused for image generation)
|
|
25
|
+
memory_store: Optional memory store instance (unused)
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
List of image generation tools
|
|
29
|
+
"""
|
|
30
|
+
all_tools = []
|
|
31
|
+
|
|
32
|
+
for tool in tools_list:
|
|
33
|
+
if (tool.get('type') == 'image_generation' or
|
|
34
|
+
tool.get('toolkit_name') == 'image_generation'):
|
|
35
|
+
try:
|
|
36
|
+
if not alita_client:
|
|
37
|
+
logger.error("Alita client is required for image "
|
|
38
|
+
"generation tools")
|
|
39
|
+
continue
|
|
40
|
+
|
|
41
|
+
toolkit_instance = ImageGenerationToolkit.get_toolkit(
|
|
42
|
+
client=alita_client,
|
|
43
|
+
toolkit_name=tool.get('toolkit_name', '')
|
|
44
|
+
)
|
|
45
|
+
all_tools.extend(toolkit_instance.get_tools())
|
|
46
|
+
except Exception as e:
|
|
47
|
+
logger.error(f"Error in image generation toolkit "
|
|
48
|
+
f"get_tools: {e}")
|
|
49
|
+
logger.error(f"Tool config: {tool}")
|
|
50
|
+
raise
|
|
51
|
+
|
|
52
|
+
return all_tools
|
|
53
|
+
|
|
11
54
|
|
|
12
55
|
class ImageGenerationInput(BaseModel):
|
|
13
56
|
"""Input schema for image generation tool."""
|
|
14
|
-
prompt: str = Field(
|
|
57
|
+
prompt: str = Field(
|
|
58
|
+
description="Text prompt describing the image to generate"
|
|
59
|
+
)
|
|
15
60
|
n: int = Field(
|
|
16
61
|
default=1, description="Number of images to generate (1-10)",
|
|
17
62
|
ge=1, le=10
|
|
@@ -22,7 +67,7 @@ class ImageGenerationInput(BaseModel):
|
|
|
22
67
|
)
|
|
23
68
|
quality: str = Field(
|
|
24
69
|
default="auto",
|
|
25
|
-
description="Quality of the generated image ('low', 'medium', 'high'
|
|
70
|
+
description="Quality of the generated image ('low', 'medium', 'high')"
|
|
26
71
|
)
|
|
27
72
|
style: Optional[str] = Field(
|
|
28
73
|
default=None, description="Style of the generated image (optional)"
|
|
@@ -33,7 +78,12 @@ class ImageGenerationTool(BaseTool):
|
|
|
33
78
|
"""Tool for generating images using the Alita client."""
|
|
34
79
|
|
|
35
80
|
name: str = "generate_image"
|
|
36
|
-
description: str =
|
|
81
|
+
description: str = (
|
|
82
|
+
"Generate images from text prompts using AI models. "
|
|
83
|
+
"Returns a JSON object with 'cached_image_id' field containing a reference to the generated image data. "
|
|
84
|
+
"The cached_image_id can be used to save or process the image. "
|
|
85
|
+
"The actual image data is stored temporarily and can be retrieved using the cached_image_id reference."
|
|
86
|
+
)
|
|
37
87
|
args_schema: Type[BaseModel] = ImageGenerationInput
|
|
38
88
|
alita_client: Any = None
|
|
39
89
|
|
|
@@ -42,10 +92,10 @@ class ImageGenerationTool(BaseTool):
|
|
|
42
92
|
self.alita_client = client
|
|
43
93
|
|
|
44
94
|
def _run(self, prompt: str, n: int = 1, size: str = "auto",
|
|
45
|
-
quality: str = "auto", style: Optional[str] = None) ->
|
|
95
|
+
quality: str = "auto", style: Optional[str] = None) -> str:
|
|
46
96
|
"""Generate an image based on the provided parameters."""
|
|
47
97
|
try:
|
|
48
|
-
logger.
|
|
98
|
+
logger.debug(f"Generating image with prompt: {prompt[:50]}...")
|
|
49
99
|
|
|
50
100
|
result = self.alita_client.generate_image(
|
|
51
101
|
prompt=prompt,
|
|
@@ -55,54 +105,56 @@ class ImageGenerationTool(BaseTool):
|
|
|
55
105
|
style=style
|
|
56
106
|
)
|
|
57
107
|
|
|
58
|
-
# Return
|
|
108
|
+
# Return simple JSON structure with reference ID instead of full base64
|
|
59
109
|
if 'data' in result:
|
|
60
110
|
images = result['data']
|
|
61
|
-
content_chunks = []
|
|
62
111
|
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
112
|
+
# Process all images with unified structure
|
|
113
|
+
images_list = []
|
|
114
|
+
for idx, image_data in enumerate(images, 1):
|
|
115
|
+
if not image_data.get('b64_json'):
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
cached_image_id = f"img_{uuid.uuid4().hex[:12]}"
|
|
119
|
+
|
|
120
|
+
# Store in cache
|
|
121
|
+
if hasattr(self.alita_client, '_generated_images_cache'):
|
|
122
|
+
self.alita_client._generated_images_cache[cached_image_id] = {
|
|
123
|
+
'base64_data': image_data['b64_json']
|
|
124
|
+
}
|
|
125
|
+
logger.debug(f"Stored generated image in cache with ID: {cached_image_id}")
|
|
126
|
+
|
|
127
|
+
images_list.append({
|
|
128
|
+
"image_number": idx,
|
|
129
|
+
"image_type": "png",
|
|
130
|
+
"cached_image_id": cached_image_id
|
|
73
131
|
})
|
|
74
132
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"image_url": {
|
|
81
|
-
"url": image_data['url']
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
elif image_data.get('b64_json'):
|
|
85
|
-
content_chunks.append({
|
|
86
|
-
"type": "image_url",
|
|
87
|
-
"image_url": {
|
|
88
|
-
"url": f"data:image/png;base64,{image_data['b64_json']}"
|
|
89
|
-
}
|
|
90
|
-
})
|
|
133
|
+
if not images_list:
|
|
134
|
+
return json.dumps({
|
|
135
|
+
"status": "error",
|
|
136
|
+
"message": "No base64 image data found"
|
|
137
|
+
})
|
|
91
138
|
|
|
92
|
-
return
|
|
139
|
+
return json.dumps({
|
|
140
|
+
"status": "success",
|
|
141
|
+
"prompt": prompt,
|
|
142
|
+
"total_images": len(images_list),
|
|
143
|
+
"images": images_list
|
|
144
|
+
})
|
|
93
145
|
|
|
94
|
-
# Fallback to
|
|
95
|
-
return
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
}
|
|
146
|
+
# Fallback to error response if no images in result
|
|
147
|
+
return json.dumps({
|
|
148
|
+
"status": "error",
|
|
149
|
+
"message": f"Image generation completed but no images returned: {result}"
|
|
150
|
+
})
|
|
99
151
|
|
|
100
152
|
except Exception as e:
|
|
101
153
|
logger.error(f"Error generating image: {e}")
|
|
102
|
-
return
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
}
|
|
154
|
+
return json.dumps({
|
|
155
|
+
"status": "error",
|
|
156
|
+
"message": f"Error generating image: {str(e)}"
|
|
157
|
+
})
|
|
106
158
|
|
|
107
159
|
async def _arun(self, prompt: str, n: int = 1, size: str = "256x256",
|
|
108
160
|
quality: str = "auto",
|
|
@@ -114,3 +166,53 @@ class ImageGenerationTool(BaseTool):
|
|
|
114
166
|
def create_image_generation_tool(client):
|
|
115
167
|
"""Create an image generation tool with the provided Alita client."""
|
|
116
168
|
return ImageGenerationTool(client=client)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class ImageGenerationToolkit(BaseToolkit):
|
|
172
|
+
"""Toolkit for image generation tools."""
|
|
173
|
+
tools: List[BaseTool] = []
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def toolkit_config_schema() -> BaseModel:
|
|
177
|
+
"""Get the configuration schema for the image generation toolkit."""
|
|
178
|
+
# Create sample tool to get schema
|
|
179
|
+
sample_tool = ImageGenerationTool(client=None)
|
|
180
|
+
selected_tools = {sample_tool.name: sample_tool.args_schema.schema()}
|
|
181
|
+
|
|
182
|
+
return create_model(
|
|
183
|
+
'image_generation',
|
|
184
|
+
selected_tools=(
|
|
185
|
+
List[Literal[tuple(selected_tools)]],
|
|
186
|
+
Field(
|
|
187
|
+
default=[],
|
|
188
|
+
json_schema_extra={'args_schemas': selected_tools}
|
|
189
|
+
)
|
|
190
|
+
),
|
|
191
|
+
__config__=ConfigDict(json_schema_extra={
|
|
192
|
+
'metadata': {
|
|
193
|
+
"label": "Image Generation",
|
|
194
|
+
"icon_url": "image_generation.svg",
|
|
195
|
+
"hidden": True,
|
|
196
|
+
"categories": ["internal_tool"],
|
|
197
|
+
"extra_categories": ["image generation"],
|
|
198
|
+
}
|
|
199
|
+
})
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def get_toolkit(cls, client=None, **kwargs):
|
|
204
|
+
"""
|
|
205
|
+
Get toolkit with image generation tools.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
client: Alita client instance (required)
|
|
209
|
+
**kwargs: Additional arguments
|
|
210
|
+
"""
|
|
211
|
+
if not client:
|
|
212
|
+
raise ValueError("Alita client is required for image generation")
|
|
213
|
+
|
|
214
|
+
tools = [ImageGenerationTool(client=client)]
|
|
215
|
+
return cls(tools=tools)
|
|
216
|
+
|
|
217
|
+
def get_tools(self):
|
|
218
|
+
return self.tools
|