alita-sdk 0.3.257__py3-none-any.whl → 0.3.584__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.

Files changed (281) hide show
  1. alita_sdk/cli/__init__.py +10 -0
  2. alita_sdk/cli/__main__.py +17 -0
  3. alita_sdk/cli/agent/__init__.py +5 -0
  4. alita_sdk/cli/agent/default.py +258 -0
  5. alita_sdk/cli/agent_executor.py +155 -0
  6. alita_sdk/cli/agent_loader.py +215 -0
  7. alita_sdk/cli/agent_ui.py +228 -0
  8. alita_sdk/cli/agents.py +3794 -0
  9. alita_sdk/cli/callbacks.py +647 -0
  10. alita_sdk/cli/cli.py +168 -0
  11. alita_sdk/cli/config.py +306 -0
  12. alita_sdk/cli/context/__init__.py +30 -0
  13. alita_sdk/cli/context/cleanup.py +198 -0
  14. alita_sdk/cli/context/manager.py +731 -0
  15. alita_sdk/cli/context/message.py +285 -0
  16. alita_sdk/cli/context/strategies.py +289 -0
  17. alita_sdk/cli/context/token_estimation.py +127 -0
  18. alita_sdk/cli/formatting.py +182 -0
  19. alita_sdk/cli/input_handler.py +419 -0
  20. alita_sdk/cli/inventory.py +1073 -0
  21. alita_sdk/cli/mcp_loader.py +315 -0
  22. alita_sdk/cli/toolkit.py +327 -0
  23. alita_sdk/cli/toolkit_loader.py +85 -0
  24. alita_sdk/cli/tools/__init__.py +43 -0
  25. alita_sdk/cli/tools/approval.py +224 -0
  26. alita_sdk/cli/tools/filesystem.py +1751 -0
  27. alita_sdk/cli/tools/planning.py +389 -0
  28. alita_sdk/cli/tools/terminal.py +414 -0
  29. alita_sdk/community/__init__.py +72 -12
  30. alita_sdk/community/inventory/__init__.py +236 -0
  31. alita_sdk/community/inventory/config.py +257 -0
  32. alita_sdk/community/inventory/enrichment.py +2137 -0
  33. alita_sdk/community/inventory/extractors.py +1469 -0
  34. alita_sdk/community/inventory/ingestion.py +3172 -0
  35. alita_sdk/community/inventory/knowledge_graph.py +1457 -0
  36. alita_sdk/community/inventory/parsers/__init__.py +218 -0
  37. alita_sdk/community/inventory/parsers/base.py +295 -0
  38. alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
  39. alita_sdk/community/inventory/parsers/go_parser.py +851 -0
  40. alita_sdk/community/inventory/parsers/html_parser.py +389 -0
  41. alita_sdk/community/inventory/parsers/java_parser.py +593 -0
  42. alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
  43. alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
  44. alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
  45. alita_sdk/community/inventory/parsers/python_parser.py +604 -0
  46. alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
  47. alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
  48. alita_sdk/community/inventory/parsers/text_parser.py +322 -0
  49. alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
  50. alita_sdk/community/inventory/patterns/__init__.py +61 -0
  51. alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
  52. alita_sdk/community/inventory/patterns/loader.py +348 -0
  53. alita_sdk/community/inventory/patterns/registry.py +198 -0
  54. alita_sdk/community/inventory/presets.py +535 -0
  55. alita_sdk/community/inventory/retrieval.py +1403 -0
  56. alita_sdk/community/inventory/toolkit.py +173 -0
  57. alita_sdk/community/inventory/toolkit_utils.py +176 -0
  58. alita_sdk/community/inventory/visualize.py +1370 -0
  59. alita_sdk/configurations/__init__.py +11 -0
  60. alita_sdk/configurations/ado.py +148 -2
  61. alita_sdk/configurations/azure_search.py +1 -1
  62. alita_sdk/configurations/bigquery.py +1 -1
  63. alita_sdk/configurations/bitbucket.py +94 -2
  64. alita_sdk/configurations/browser.py +18 -0
  65. alita_sdk/configurations/carrier.py +19 -0
  66. alita_sdk/configurations/confluence.py +130 -1
  67. alita_sdk/configurations/delta_lake.py +1 -1
  68. alita_sdk/configurations/figma.py +76 -5
  69. alita_sdk/configurations/github.py +65 -1
  70. alita_sdk/configurations/gitlab.py +81 -0
  71. alita_sdk/configurations/google_places.py +17 -0
  72. alita_sdk/configurations/jira.py +103 -0
  73. alita_sdk/configurations/openapi.py +323 -0
  74. alita_sdk/configurations/postman.py +1 -1
  75. alita_sdk/configurations/qtest.py +72 -3
  76. alita_sdk/configurations/report_portal.py +115 -0
  77. alita_sdk/configurations/salesforce.py +19 -0
  78. alita_sdk/configurations/service_now.py +1 -12
  79. alita_sdk/configurations/sharepoint.py +167 -0
  80. alita_sdk/configurations/sonar.py +18 -0
  81. alita_sdk/configurations/sql.py +20 -0
  82. alita_sdk/configurations/testio.py +101 -0
  83. alita_sdk/configurations/testrail.py +88 -0
  84. alita_sdk/configurations/xray.py +94 -1
  85. alita_sdk/configurations/zephyr_enterprise.py +94 -1
  86. alita_sdk/configurations/zephyr_essential.py +95 -0
  87. alita_sdk/runtime/clients/artifact.py +21 -4
  88. alita_sdk/runtime/clients/client.py +458 -67
  89. alita_sdk/runtime/clients/mcp_discovery.py +342 -0
  90. alita_sdk/runtime/clients/mcp_manager.py +262 -0
  91. alita_sdk/runtime/clients/sandbox_client.py +352 -0
  92. alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
  93. alita_sdk/runtime/langchain/assistant.py +183 -43
  94. alita_sdk/runtime/langchain/constants.py +647 -1
  95. alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
  96. alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +209 -31
  97. alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +1 -1
  98. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
  99. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -3
  100. alita_sdk/runtime/langchain/document_loaders/AlitaMarkdownLoader.py +66 -0
  101. alita_sdk/runtime/langchain/document_loaders/AlitaPDFLoader.py +79 -10
  102. alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +52 -15
  103. alita_sdk/runtime/langchain/document_loaders/AlitaPythonLoader.py +9 -0
  104. alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -4
  105. alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +15 -2
  106. alita_sdk/runtime/langchain/document_loaders/ImageParser.py +30 -0
  107. alita_sdk/runtime/langchain/document_loaders/constants.py +189 -41
  108. alita_sdk/runtime/langchain/interfaces/llm_processor.py +4 -2
  109. alita_sdk/runtime/langchain/langraph_agent.py +493 -105
  110. alita_sdk/runtime/langchain/utils.py +118 -8
  111. alita_sdk/runtime/llms/preloaded.py +2 -6
  112. alita_sdk/runtime/models/mcp_models.py +61 -0
  113. alita_sdk/runtime/skills/__init__.py +91 -0
  114. alita_sdk/runtime/skills/callbacks.py +498 -0
  115. alita_sdk/runtime/skills/discovery.py +540 -0
  116. alita_sdk/runtime/skills/executor.py +610 -0
  117. alita_sdk/runtime/skills/input_builder.py +371 -0
  118. alita_sdk/runtime/skills/models.py +330 -0
  119. alita_sdk/runtime/skills/registry.py +355 -0
  120. alita_sdk/runtime/skills/skill_runner.py +330 -0
  121. alita_sdk/runtime/toolkits/__init__.py +28 -0
  122. alita_sdk/runtime/toolkits/application.py +14 -4
  123. alita_sdk/runtime/toolkits/artifact.py +25 -9
  124. alita_sdk/runtime/toolkits/datasource.py +13 -6
  125. alita_sdk/runtime/toolkits/mcp.py +782 -0
  126. alita_sdk/runtime/toolkits/planning.py +178 -0
  127. alita_sdk/runtime/toolkits/skill_router.py +238 -0
  128. alita_sdk/runtime/toolkits/subgraph.py +11 -6
  129. alita_sdk/runtime/toolkits/tools.py +314 -70
  130. alita_sdk/runtime/toolkits/vectorstore.py +11 -5
  131. alita_sdk/runtime/tools/__init__.py +24 -0
  132. alita_sdk/runtime/tools/application.py +16 -4
  133. alita_sdk/runtime/tools/artifact.py +367 -33
  134. alita_sdk/runtime/tools/data_analysis.py +183 -0
  135. alita_sdk/runtime/tools/function.py +100 -4
  136. alita_sdk/runtime/tools/graph.py +81 -0
  137. alita_sdk/runtime/tools/image_generation.py +218 -0
  138. alita_sdk/runtime/tools/llm.py +1032 -177
  139. alita_sdk/runtime/tools/loop.py +3 -1
  140. alita_sdk/runtime/tools/loop_output.py +3 -1
  141. alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
  142. alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
  143. alita_sdk/runtime/tools/mcp_server_tool.py +3 -1
  144. alita_sdk/runtime/tools/planning/__init__.py +36 -0
  145. alita_sdk/runtime/tools/planning/models.py +246 -0
  146. alita_sdk/runtime/tools/planning/wrapper.py +607 -0
  147. alita_sdk/runtime/tools/router.py +2 -1
  148. alita_sdk/runtime/tools/sandbox.py +375 -0
  149. alita_sdk/runtime/tools/skill_router.py +776 -0
  150. alita_sdk/runtime/tools/tool.py +3 -1
  151. alita_sdk/runtime/tools/vectorstore.py +69 -65
  152. alita_sdk/runtime/tools/vectorstore_base.py +163 -90
  153. alita_sdk/runtime/utils/AlitaCallback.py +137 -21
  154. alita_sdk/runtime/utils/constants.py +5 -1
  155. alita_sdk/runtime/utils/mcp_client.py +492 -0
  156. alita_sdk/runtime/utils/mcp_oauth.py +361 -0
  157. alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
  158. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  159. alita_sdk/runtime/utils/streamlit.py +41 -14
  160. alita_sdk/runtime/utils/toolkit_utils.py +28 -9
  161. alita_sdk/runtime/utils/utils.py +48 -0
  162. alita_sdk/tools/__init__.py +135 -37
  163. alita_sdk/tools/ado/__init__.py +2 -2
  164. alita_sdk/tools/ado/repos/__init__.py +16 -19
  165. alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
  166. alita_sdk/tools/ado/test_plan/__init__.py +27 -8
  167. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
  168. alita_sdk/tools/ado/wiki/__init__.py +28 -12
  169. alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
  170. alita_sdk/tools/ado/work_item/__init__.py +28 -12
  171. alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
  172. alita_sdk/tools/advanced_jira_mining/__init__.py +13 -8
  173. alita_sdk/tools/aws/delta_lake/__init__.py +15 -11
  174. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  175. alita_sdk/tools/azure_ai/search/__init__.py +14 -8
  176. alita_sdk/tools/base/tool.py +5 -1
  177. alita_sdk/tools/base_indexer_toolkit.py +454 -110
  178. alita_sdk/tools/bitbucket/__init__.py +28 -19
  179. alita_sdk/tools/bitbucket/api_wrapper.py +285 -27
  180. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
  181. alita_sdk/tools/browser/__init__.py +41 -16
  182. alita_sdk/tools/browser/crawler.py +3 -1
  183. alita_sdk/tools/browser/utils.py +15 -6
  184. alita_sdk/tools/carrier/__init__.py +18 -17
  185. alita_sdk/tools/carrier/backend_reports_tool.py +8 -4
  186. alita_sdk/tools/carrier/excel_reporter.py +8 -4
  187. alita_sdk/tools/chunkers/__init__.py +3 -1
  188. alita_sdk/tools/chunkers/code/codeparser.py +1 -1
  189. alita_sdk/tools/chunkers/sematic/json_chunker.py +2 -1
  190. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  191. alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
  192. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  193. alita_sdk/tools/cloud/aws/__init__.py +12 -7
  194. alita_sdk/tools/cloud/azure/__init__.py +12 -7
  195. alita_sdk/tools/cloud/gcp/__init__.py +12 -7
  196. alita_sdk/tools/cloud/k8s/__init__.py +12 -7
  197. alita_sdk/tools/code/linter/__init__.py +10 -8
  198. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  199. alita_sdk/tools/code/sonar/__init__.py +21 -13
  200. alita_sdk/tools/code_indexer_toolkit.py +199 -0
  201. alita_sdk/tools/confluence/__init__.py +22 -14
  202. alita_sdk/tools/confluence/api_wrapper.py +197 -58
  203. alita_sdk/tools/confluence/loader.py +14 -2
  204. alita_sdk/tools/custom_open_api/__init__.py +12 -5
  205. alita_sdk/tools/elastic/__init__.py +11 -8
  206. alita_sdk/tools/elitea_base.py +546 -64
  207. alita_sdk/tools/figma/__init__.py +60 -11
  208. alita_sdk/tools/figma/api_wrapper.py +1400 -167
  209. alita_sdk/tools/figma/figma_client.py +73 -0
  210. alita_sdk/tools/figma/toon_tools.py +2748 -0
  211. alita_sdk/tools/github/__init__.py +18 -17
  212. alita_sdk/tools/github/api_wrapper.py +9 -26
  213. alita_sdk/tools/github/github_client.py +81 -12
  214. alita_sdk/tools/github/schemas.py +2 -1
  215. alita_sdk/tools/github/tool.py +5 -1
  216. alita_sdk/tools/gitlab/__init__.py +19 -13
  217. alita_sdk/tools/gitlab/api_wrapper.py +256 -80
  218. alita_sdk/tools/gitlab_org/__init__.py +14 -10
  219. alita_sdk/tools/google/bigquery/__init__.py +14 -13
  220. alita_sdk/tools/google/bigquery/tool.py +5 -1
  221. alita_sdk/tools/google_places/__init__.py +21 -11
  222. alita_sdk/tools/jira/__init__.py +22 -11
  223. alita_sdk/tools/jira/api_wrapper.py +315 -168
  224. alita_sdk/tools/keycloak/__init__.py +11 -8
  225. alita_sdk/tools/localgit/__init__.py +9 -3
  226. alita_sdk/tools/localgit/local_git.py +62 -54
  227. alita_sdk/tools/localgit/tool.py +5 -1
  228. alita_sdk/tools/memory/__init__.py +38 -14
  229. alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
  230. alita_sdk/tools/ocr/__init__.py +11 -8
  231. alita_sdk/tools/openapi/__init__.py +491 -106
  232. alita_sdk/tools/openapi/api_wrapper.py +1357 -0
  233. alita_sdk/tools/openapi/tool.py +20 -0
  234. alita_sdk/tools/pandas/__init__.py +20 -12
  235. alita_sdk/tools/pandas/api_wrapper.py +40 -45
  236. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  237. alita_sdk/tools/postman/__init__.py +11 -11
  238. alita_sdk/tools/postman/api_wrapper.py +19 -8
  239. alita_sdk/tools/postman/postman_analysis.py +8 -1
  240. alita_sdk/tools/pptx/__init__.py +11 -10
  241. alita_sdk/tools/qtest/__init__.py +22 -14
  242. alita_sdk/tools/qtest/api_wrapper.py +1784 -88
  243. alita_sdk/tools/rally/__init__.py +13 -10
  244. alita_sdk/tools/report_portal/__init__.py +23 -16
  245. alita_sdk/tools/salesforce/__init__.py +22 -16
  246. alita_sdk/tools/servicenow/__init__.py +21 -16
  247. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  248. alita_sdk/tools/sharepoint/__init__.py +17 -14
  249. alita_sdk/tools/sharepoint/api_wrapper.py +179 -39
  250. alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
  251. alita_sdk/tools/sharepoint/utils.py +8 -2
  252. alita_sdk/tools/slack/__init__.py +13 -8
  253. alita_sdk/tools/sql/__init__.py +22 -19
  254. alita_sdk/tools/sql/api_wrapper.py +71 -23
  255. alita_sdk/tools/testio/__init__.py +21 -13
  256. alita_sdk/tools/testrail/__init__.py +13 -11
  257. alita_sdk/tools/testrail/api_wrapper.py +214 -46
  258. alita_sdk/tools/utils/__init__.py +28 -4
  259. alita_sdk/tools/utils/content_parser.py +241 -55
  260. alita_sdk/tools/utils/text_operations.py +254 -0
  261. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
  262. alita_sdk/tools/xray/__init__.py +18 -14
  263. alita_sdk/tools/xray/api_wrapper.py +58 -113
  264. alita_sdk/tools/yagmail/__init__.py +9 -3
  265. alita_sdk/tools/zephyr/__init__.py +12 -7
  266. alita_sdk/tools/zephyr_enterprise/__init__.py +16 -9
  267. alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
  268. alita_sdk/tools/zephyr_essential/__init__.py +16 -10
  269. alita_sdk/tools/zephyr_essential/api_wrapper.py +297 -54
  270. alita_sdk/tools/zephyr_essential/client.py +6 -4
  271. alita_sdk/tools/zephyr_scale/__init__.py +13 -8
  272. alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
  273. alita_sdk/tools/zephyr_squad/__init__.py +12 -7
  274. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/METADATA +184 -37
  275. alita_sdk-0.3.584.dist-info/RECORD +452 -0
  276. alita_sdk-0.3.584.dist-info/entry_points.txt +2 -0
  277. alita_sdk/tools/bitbucket/tools.py +0 -304
  278. alita_sdk-0.3.257.dist-info/RECORD +0 -343
  279. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/WHEEL +0 -0
  280. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/licenses/LICENSE +0 -0
  281. {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,178 @@
1
+ """
2
+ PlanningToolkit - Runtime toolkit for agent plan management.
3
+
4
+ Provides tools for creating, tracking, and completing multi-step execution plans.
5
+ Supports two storage backends:
6
+ 1. PostgreSQL - when pgvector_configuration with connection_string is provided
7
+ 2. Filesystem - when no connection string (local CLI usage)
8
+ """
9
+
10
+ from typing import ClassVar, List, Any, Literal, Optional, Callable
11
+
12
+ from langchain_community.agent_toolkits.base import BaseToolkit
13
+ from langchain_core.tools import BaseTool
14
+ from pydantic import create_model, BaseModel, ConfigDict, Field
15
+ from pydantic.fields import FieldInfo
16
+
17
+ from ..tools.planning import PlanningWrapper
18
+ from ...tools.base.tool import BaseAction
19
+ from ...tools.utils import clean_string, get_max_toolkit_length
20
+
21
+
22
+ class PlanningToolkit(BaseToolkit):
23
+ """
24
+ Toolkit for agent plan management.
25
+
26
+ Provides tools for creating, updating, and tracking execution plans.
27
+ Supports PostgreSQL (production) and filesystem (local) storage backends.
28
+ Plans are scoped by conversation_id.
29
+ """
30
+ tools: List[BaseTool] = []
31
+ _toolkit_max_length: ClassVar[int] = 50 # Use ClassVar to avoid Pydantic treating it as field
32
+
33
+ @staticmethod
34
+ def toolkit_config_schema() -> BaseModel:
35
+ """
36
+ Returns the configuration schema for the Planning toolkit.
37
+
38
+ Used by the UI to generate the toolkit configuration form.
39
+ """
40
+ # Define available tools
41
+ selected_tools = {
42
+ 'update_plan': {
43
+ 'title': 'UpdatePlanInput',
44
+ 'type': 'object',
45
+ 'properties': {
46
+ 'title': {'type': 'string', 'description': "Title for the plan"},
47
+ 'steps': {'type': 'array', 'items': {'type': 'string'}, 'description': "List of step descriptions"},
48
+ 'conversation_id': {'type': 'string', 'description': "Conversation ID (auto-injected)"}
49
+ },
50
+ 'required': ['title', 'steps', 'conversation_id']
51
+ },
52
+ 'complete_step': {
53
+ 'title': 'CompleteStepInput',
54
+ 'type': 'object',
55
+ 'properties': {
56
+ 'step_number': {'type': 'integer', 'description': "Step number to complete (1-indexed)"},
57
+ 'conversation_id': {'type': 'string', 'description': "Conversation ID (auto-injected)"}
58
+ },
59
+ 'required': ['step_number', 'conversation_id']
60
+ },
61
+ 'get_plan_status': {
62
+ 'title': 'GetPlanStatusInput',
63
+ 'type': 'object',
64
+ 'properties': {
65
+ 'conversation_id': {'type': 'string', 'description': "Conversation ID (auto-injected)"}
66
+ },
67
+ 'required': ['conversation_id']
68
+ },
69
+ 'delete_plan': {
70
+ 'title': 'DeletePlanInput',
71
+ 'type': 'object',
72
+ 'properties': {
73
+ 'conversation_id': {'type': 'string', 'description': "Conversation ID (auto-injected)"}
74
+ },
75
+ 'required': ['conversation_id']
76
+ }
77
+ }
78
+
79
+ PlanningToolkit._toolkit_max_length = get_max_toolkit_length(selected_tools)
80
+
81
+ return create_model(
82
+ "planning",
83
+ # Tool selection
84
+ selected_tools=(
85
+ List[Literal[tuple(selected_tools)]],
86
+ Field(
87
+ default=list(selected_tools.keys()),
88
+ json_schema_extra={'args_schemas': selected_tools}
89
+ )
90
+ ),
91
+ __config__=ConfigDict(
92
+ json_schema_extra={
93
+ 'metadata': {
94
+ "label": "Planning",
95
+ "description": "Tools for managing multi-step execution plans with progress tracking. Uses PostgreSQL when configured, filesystem otherwise.",
96
+ "icon_url": None,
97
+ "max_length": PlanningToolkit._toolkit_max_length,
98
+ "categories": ["planning", "internal_tool"],
99
+ "extra_categories": ["task management", "todo", "progress tracking"]
100
+ }
101
+ }
102
+ )
103
+ )
104
+
105
+ @classmethod
106
+ def get_toolkit(
107
+ cls,
108
+ toolkit_name: Optional[str] = None,
109
+ selected_tools: Optional[List[str]] = None,
110
+ pgvector_configuration: Optional[dict] = None,
111
+ storage_dir: Optional[str] = None,
112
+ plan_callback: Optional[Any] = None,
113
+ conversation_id: Optional[str] = None,
114
+ **kwargs
115
+ ):
116
+ """
117
+ Create a PlanningToolkit instance with configured tools.
118
+
119
+ Args:
120
+ toolkit_name: Optional name prefix for tools
121
+ selected_tools: List of tool names to include (default: all)
122
+ pgvector_configuration: PostgreSQL configuration dict with connection_string.
123
+ If not provided, uses filesystem storage.
124
+ storage_dir: Directory for filesystem storage (when no pgvector_configuration)
125
+ plan_callback: Optional callback function called when plan changes (for CLI UI)
126
+ conversation_id: Conversation ID for scoping plans.
127
+ For server: from elitea_core payload. For CLI: session_id.
128
+ **kwargs: Additional configuration options
129
+
130
+ Returns:
131
+ PlanningToolkit instance with configured tools
132
+ """
133
+ if selected_tools is None:
134
+ selected_tools = ['update_plan', 'complete_step', 'get_plan_status', 'delete_plan']
135
+
136
+ tools = []
137
+
138
+ # Extract connection string from pgvector configuration (if provided)
139
+ connection_string = None
140
+ if pgvector_configuration:
141
+ connection_string = pgvector_configuration.get('connection_string', '')
142
+ if hasattr(connection_string, 'get_secret_value'):
143
+ connection_string = connection_string.get_secret_value()
144
+
145
+ # Create wrapper - it will auto-select storage backend
146
+ wrapper = PlanningWrapper(
147
+ connection_string=connection_string if connection_string else None,
148
+ conversation_id=conversation_id,
149
+ storage_dir=storage_dir,
150
+ plan_callback=plan_callback,
151
+ )
152
+
153
+ # Use clean toolkit name for context (max 1000 chars in description)
154
+ toolkit_context = f" [Toolkit: {clean_string(toolkit_name, 0)}]" if toolkit_name else ''
155
+
156
+ # Create tools from wrapper
157
+ available_tools = wrapper.get_available_tools()
158
+ for tool in available_tools:
159
+ if tool["name"] not in selected_tools:
160
+ continue
161
+
162
+ # Add toolkit context to description with character limit
163
+ description = tool["description"]
164
+ if toolkit_context and len(description + toolkit_context) <= 1000:
165
+ description = description + toolkit_context
166
+
167
+ tools.append(BaseAction(
168
+ api_wrapper=wrapper,
169
+ name=tool["name"],
170
+ description=description,
171
+ args_schema=tool["args_schema"]
172
+ ))
173
+
174
+ return cls(tools=tools)
175
+
176
+ def get_tools(self) -> List[BaseTool]:
177
+ """Return the list of configured tools."""
178
+ return self.tools
@@ -0,0 +1,238 @@
1
+ """
2
+ SkillRouter Toolkit for configuring and accessing specialized skills.
3
+
4
+ This toolkit provides a configurable way to set up the skill router with
5
+ specific skills from filesystem or platform-hosted agents/pipelines.
6
+ """
7
+
8
+ from typing import List, Optional, TYPE_CHECKING
9
+ from pydantic import create_model, BaseModel, Field, ConfigDict
10
+ from langchain_community.agent_toolkits.base import BaseToolkit
11
+ from langchain_core.tools import BaseTool
12
+
13
+ if TYPE_CHECKING:
14
+ from alita_sdk.clients import AlitaClient
15
+
16
+ from alita_sdk.tools.base.tool import BaseAction
17
+ from alita_sdk.tools.utils import clean_string
18
+ from ..skills import SkillsRegistry, SkillMetadata, SkillType, SkillSource
19
+ from ..tools.skill_router import SkillRouterWrapper
20
+
21
+
22
+ class SkillConfig(BaseModel):
23
+ """Configuration for a single skill."""
24
+
25
+ # Platform skill fields (type is implicit from parent field: agents or pipelines)
26
+ id: int = Field(description="Platform ID (for agent/pipeline skills)")
27
+ version_id: int = Field(description="Platform version ID (for agent/pipeline skills)")
28
+ name: Optional[str] = Field(default=None, description="Skill name (optional override)")
29
+
30
+
31
+ class SkillRouterToolkit(BaseToolkit):
32
+ """Toolkit for configuring skill router with specific skills."""
33
+
34
+ tools: List[BaseTool] = []
35
+
36
+ @staticmethod
37
+ def toolkit_config_schema() -> BaseModel:
38
+ """Define the configuration schema for the skill router toolkit."""
39
+ # Get available tools for selected_tools field
40
+ selected_tools_options = {x['name']: x['args_schema'].schema() for x in SkillRouterWrapper.model_construct().get_available_tools()}
41
+
42
+ return create_model(
43
+ "skill_router",
44
+ # Separate fields for agents and pipelines - optional but default to empty lists
45
+ agents=(Optional[List[SkillConfig]], Field(
46
+ description="List of agents to make available as skills",
47
+ default=[],
48
+ json_schema_extra={
49
+ "agent_tags": ["skill"]
50
+ }
51
+ )),
52
+ pipelines=(Optional[List[SkillConfig]], Field(
53
+ description="List of pipelines to make available as skills",
54
+ default=[],
55
+ json_schema_extra={
56
+ "pipeline_tags": ["skill"]
57
+ }
58
+ )),
59
+ prompt=(Optional[str], Field(
60
+ description="Custom system prompt for skill routing",
61
+ default="",
62
+ json_schema_extra={"lines": 4}
63
+ )),
64
+ timeout=(Optional[int], Field(description="Default timeout in seconds for skill execution", default=300)),
65
+ execution_mode=(Optional[str], Field(
66
+ description="Default execution mode for skills",
67
+ default=None,
68
+ json_schema_extra={"enum": ["subprocess", "remote"]}
69
+ )),
70
+ selected_tools=(List[str], Field(
71
+ description="List of tools to enable",
72
+ default=list(selected_tools_options.keys()),
73
+ json_schema_extra={'args_schemas': selected_tools_options}
74
+ )),
75
+ __config__=ConfigDict(json_schema_extra={'metadata': {"label": "Skill Router", "icon_url": None, "hidden": True}})
76
+ )
77
+
78
+ @classmethod
79
+ def get_toolkit(
80
+ cls,
81
+ client: 'AlitaClient',
82
+ llm = None,
83
+ toolkit_name: Optional[str] = None,
84
+ selected_tools: List[str] = None,
85
+ agents: List[SkillConfig] = None,
86
+ pipelines: List[SkillConfig] = None,
87
+ prompt: Optional[str] = None,
88
+ timeout: Optional[int] = None,
89
+ execution_mode: Optional[str] = None
90
+ ):
91
+ """Create a skill router toolkit with configured skills."""
92
+
93
+ if selected_tools is None:
94
+ selected_tools = []
95
+
96
+ # Create a custom registry for this toolkit
97
+ registry = SkillsRegistry(search_paths=[])
98
+
99
+ # Helper function to process skill configs
100
+ def add_skills_to_registry(skill_configs, skill_type):
101
+ if skill_configs:
102
+ for skill_config_dict in skill_configs:
103
+ # Convert dict to SkillConfig object
104
+ skill_config = SkillConfig(**skill_config_dict)
105
+ skill_metadata = cls._create_skill_from_config(skill_config, client, skill_type)
106
+ if skill_metadata:
107
+ # Add skill to registry manually
108
+ registry.discovery.cache[skill_metadata.name] = skill_metadata
109
+
110
+ # Add configured agents (if provided)
111
+ add_skills_to_registry(agents or [], "agent")
112
+
113
+ # Add configured pipelines (if provided)
114
+ add_skills_to_registry(pipelines or [], "pipeline")
115
+
116
+ # Create skill router wrapper with custom configuration
117
+ wrapper = SkillRouterWrapper(
118
+ registry=registry,
119
+ alita_client=client,
120
+ llm=llm,
121
+ enable_callbacks=True,
122
+ default_timeout=timeout,
123
+ default_execution_mode=execution_mode,
124
+ custom_prompt=prompt
125
+ )
126
+
127
+ # Get available tools from wrapper
128
+ available_tools = wrapper.get_available_tools()
129
+
130
+ # Filter by selected_tools if provided
131
+ tools = []
132
+ toolkit_context = f" [Toolkit: {clean_string(toolkit_name, 0)}]" if toolkit_name else ''
133
+
134
+ for tool in available_tools:
135
+ if selected_tools:
136
+ if tool["name"] not in selected_tools:
137
+ continue
138
+
139
+ # Add toolkit context to description with character limit
140
+ description = tool["description"]
141
+ if toolkit_context and len(description + toolkit_context) <= 1000:
142
+ description = description + toolkit_context
143
+
144
+ # Wrap in BaseAction
145
+ tools.append(BaseAction(
146
+ api_wrapper=wrapper,
147
+ name=tool["name"],
148
+ description=description,
149
+ args_schema=tool["args_schema"],
150
+ metadata={"toolkit_name": toolkit_name, "toolkit_type": "skill_router"} if toolkit_name else {}
151
+ ))
152
+
153
+ return cls(tools=tools)
154
+
155
+ @classmethod
156
+ def _create_skill_from_config(cls, config: SkillConfig, client: 'AlitaClient', skill_type: str) -> Optional[SkillMetadata]:
157
+ """Create SkillMetadata from SkillConfig.
158
+
159
+ Args:
160
+ config: SkillConfig with id, version_id, and optional name
161
+ client: AlitaClient for fetching skill details
162
+ skill_type: Either "agent" or "pipeline" (from parent field)
163
+ """
164
+ try:
165
+ # Get skill details from platform
166
+ if skill_type == "agent":
167
+ skill_details = cls._get_agent_details(client, config.id, config.version_id)
168
+ metadata_type = SkillType.AGENT
169
+ else: # pipeline
170
+ skill_details = cls._get_pipeline_details(client, config.id, config.version_id)
171
+ metadata_type = SkillType.PIPELINE
172
+
173
+ # Create SkillMetadata for platform skill
174
+ return SkillMetadata(
175
+ name=config.name or skill_details.get('name', f"{skill_type}_{config.id}"),
176
+ skill_type=metadata_type,
177
+ source=SkillSource.PLATFORM,
178
+ id=config.id,
179
+ version_id=config.version_id,
180
+ description=skill_details.get('description', ''),
181
+ capabilities=skill_details.get('capabilities', []),
182
+ tags=skill_details.get('tags', []),
183
+ version=skill_details.get('version', '1.0.0'),
184
+ # Set default execution config - platform skills run remotely
185
+ execution={"mode": "remote", "timeout": 300},
186
+ results={"format": "text_with_links"},
187
+ inputs={},
188
+ outputs={}
189
+ )
190
+
191
+ except Exception as e:
192
+ import logging
193
+ logging.getLogger(__name__).error(f"Failed to create skill from config {config}: {e}")
194
+ return None
195
+
196
+ @classmethod
197
+ def _get_agent_details(cls, client: 'AlitaClient', agent_id: int, version_id: int) -> dict:
198
+ """Get agent details from platform."""
199
+ try:
200
+ app_details = client.get_app_details(agent_id)
201
+ version_details = client.get_app_version_details(agent_id, version_id)
202
+
203
+ return {
204
+ 'name': app_details.get('name', f'agent_{agent_id}'),
205
+ 'description': app_details.get('description', ''),
206
+ 'capabilities': [], # Could be extracted from app metadata
207
+ 'tags': [], # Could be extracted from app metadata
208
+ 'version': version_details.get('version', '1.0.0')
209
+ }
210
+ except Exception as e:
211
+ import logging
212
+ logging.getLogger(__name__).error(f"Failed to get agent details for {agent_id}/{version_id}: {e}")
213
+ return {'name': f'agent_{agent_id}', 'description': 'Platform-hosted agent'}
214
+
215
+ @classmethod
216
+ def _get_pipeline_details(cls, client: 'AlitaClient', pipeline_id: int, version_id: int) -> dict:
217
+ """Get pipeline details from platform."""
218
+ try:
219
+ # For now, use the same method as agents since they use the same API
220
+ # In the future, this might use a different endpoint for pipelines
221
+ app_details = client.get_app_details(pipeline_id)
222
+ version_details = client.get_app_version_details(pipeline_id, version_id)
223
+
224
+ return {
225
+ 'name': app_details.get('name', f'pipeline_{pipeline_id}'),
226
+ 'description': app_details.get('description', ''),
227
+ 'capabilities': [], # Could be extracted from pipeline metadata
228
+ 'tags': [], # Could be extracted from pipeline metadata
229
+ 'version': version_details.get('version', '1.0.0')
230
+ }
231
+ except Exception as e:
232
+ import logging
233
+ logging.getLogger(__name__).error(f"Failed to get pipeline details for {pipeline_id}/{version_id}: {e}")
234
+ return {'name': f'pipeline_{pipeline_id}', 'description': 'Platform-hosted pipeline'}
235
+
236
+ def get_tools(self):
237
+ """Get the configured tools."""
238
+ return self.tools
@@ -1,8 +1,11 @@
1
1
  from typing import List, Any
2
2
 
3
+ from langchain_core.tools import BaseTool
4
+ from langgraph.checkpoint.memory import MemorySaver
3
5
  from langgraph.graph.state import CompiledStateGraph
4
6
 
5
7
  from ..langchain.langraph_agent import create_graph, SUBGRAPH_REGISTRY
8
+ from ..tools.graph import GraphTool
6
9
  from ..utils.utils import clean_string
7
10
 
8
11
 
@@ -16,7 +19,7 @@ class SubgraphToolkit:
16
19
  llm,
17
20
  app_api_key: str,
18
21
  selected_tools: list[str] = []
19
- ) -> List[CompiledStateGraph]:
22
+ ) -> List[BaseTool]:
20
23
  from .tools import get_tools
21
24
  # from langgraph.checkpoint.memory import MemorySaver
22
25
 
@@ -36,18 +39,20 @@ class SubgraphToolkit:
36
39
 
37
40
  # For backward compatibility, still create a compiled graph stub
38
41
  # This is mainly used for identification in the parent graph's tools list
42
+ # For now the graph toolkit will have its own ephemeral in memory checkpoint memory.
39
43
  graph = create_graph(
40
44
  client=llm,
41
45
  tools=tools,
42
46
  yaml_schema=version_details['instructions'],
43
47
  debug=False,
44
48
  store=None,
45
- memory=None,
46
- for_subgraph=True, # compile as raw subgraph
49
+ memory=MemorySaver(),
50
+ # for_subgraph=True, # compile as raw subgraph
47
51
  )
48
-
52
+
53
+ cleaned_subgraph_name = clean_string(subgraph_name)
49
54
  # Tag the graph stub for parent lookup
50
- graph.name = clean_string(subgraph_name)
55
+ graph.name = cleaned_subgraph_name
51
56
 
52
57
  # Return the compiled graph stub for backward compatibility
53
- return [graph]
58
+ return [GraphTool(description=app_details['description'], name=subgraph_name, graph=graph)]