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.
Files changed (278) 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 +156 -0
  6. alita_sdk/cli/agent_loader.py +245 -0
  7. alita_sdk/cli/agent_ui.py +228 -0
  8. alita_sdk/cli/agents.py +3113 -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/testcases/__init__.py +94 -0
  23. alita_sdk/cli/testcases/data_generation.py +119 -0
  24. alita_sdk/cli/testcases/discovery.py +96 -0
  25. alita_sdk/cli/testcases/executor.py +84 -0
  26. alita_sdk/cli/testcases/logger.py +85 -0
  27. alita_sdk/cli/testcases/parser.py +172 -0
  28. alita_sdk/cli/testcases/prompts.py +91 -0
  29. alita_sdk/cli/testcases/reporting.py +125 -0
  30. alita_sdk/cli/testcases/setup.py +108 -0
  31. alita_sdk/cli/testcases/test_runner.py +282 -0
  32. alita_sdk/cli/testcases/utils.py +39 -0
  33. alita_sdk/cli/testcases/validation.py +90 -0
  34. alita_sdk/cli/testcases/workflow.py +196 -0
  35. alita_sdk/cli/toolkit.py +327 -0
  36. alita_sdk/cli/toolkit_loader.py +85 -0
  37. alita_sdk/cli/tools/__init__.py +43 -0
  38. alita_sdk/cli/tools/approval.py +224 -0
  39. alita_sdk/cli/tools/filesystem.py +1751 -0
  40. alita_sdk/cli/tools/planning.py +389 -0
  41. alita_sdk/cli/tools/terminal.py +414 -0
  42. alita_sdk/community/__init__.py +72 -12
  43. alita_sdk/community/inventory/__init__.py +236 -0
  44. alita_sdk/community/inventory/config.py +257 -0
  45. alita_sdk/community/inventory/enrichment.py +2137 -0
  46. alita_sdk/community/inventory/extractors.py +1469 -0
  47. alita_sdk/community/inventory/ingestion.py +3172 -0
  48. alita_sdk/community/inventory/knowledge_graph.py +1457 -0
  49. alita_sdk/community/inventory/parsers/__init__.py +218 -0
  50. alita_sdk/community/inventory/parsers/base.py +295 -0
  51. alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
  52. alita_sdk/community/inventory/parsers/go_parser.py +851 -0
  53. alita_sdk/community/inventory/parsers/html_parser.py +389 -0
  54. alita_sdk/community/inventory/parsers/java_parser.py +593 -0
  55. alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
  56. alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
  57. alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
  58. alita_sdk/community/inventory/parsers/python_parser.py +604 -0
  59. alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
  60. alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
  61. alita_sdk/community/inventory/parsers/text_parser.py +322 -0
  62. alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
  63. alita_sdk/community/inventory/patterns/__init__.py +61 -0
  64. alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
  65. alita_sdk/community/inventory/patterns/loader.py +348 -0
  66. alita_sdk/community/inventory/patterns/registry.py +198 -0
  67. alita_sdk/community/inventory/presets.py +535 -0
  68. alita_sdk/community/inventory/retrieval.py +1403 -0
  69. alita_sdk/community/inventory/toolkit.py +173 -0
  70. alita_sdk/community/inventory/toolkit_utils.py +176 -0
  71. alita_sdk/community/inventory/visualize.py +1370 -0
  72. alita_sdk/configurations/__init__.py +1 -1
  73. alita_sdk/configurations/ado.py +141 -20
  74. alita_sdk/configurations/bitbucket.py +94 -2
  75. alita_sdk/configurations/confluence.py +130 -1
  76. alita_sdk/configurations/figma.py +76 -0
  77. alita_sdk/configurations/gitlab.py +91 -0
  78. alita_sdk/configurations/jira.py +103 -0
  79. alita_sdk/configurations/openapi.py +329 -0
  80. alita_sdk/configurations/qtest.py +72 -1
  81. alita_sdk/configurations/report_portal.py +96 -0
  82. alita_sdk/configurations/sharepoint.py +148 -0
  83. alita_sdk/configurations/testio.py +83 -0
  84. alita_sdk/configurations/testrail.py +88 -0
  85. alita_sdk/configurations/xray.py +93 -0
  86. alita_sdk/configurations/zephyr_enterprise.py +93 -0
  87. alita_sdk/configurations/zephyr_essential.py +75 -0
  88. alita_sdk/runtime/clients/artifact.py +3 -3
  89. alita_sdk/runtime/clients/client.py +388 -46
  90. alita_sdk/runtime/clients/mcp_discovery.py +342 -0
  91. alita_sdk/runtime/clients/mcp_manager.py +262 -0
  92. alita_sdk/runtime/clients/sandbox_client.py +8 -21
  93. alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
  94. alita_sdk/runtime/langchain/assistant.py +157 -39
  95. alita_sdk/runtime/langchain/constants.py +647 -1
  96. alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
  97. alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
  98. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
  99. alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -4
  100. alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +226 -7
  101. alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +5 -2
  102. alita_sdk/runtime/langchain/document_loaders/constants.py +40 -19
  103. alita_sdk/runtime/langchain/langraph_agent.py +405 -84
  104. alita_sdk/runtime/langchain/utils.py +106 -7
  105. alita_sdk/runtime/llms/preloaded.py +2 -6
  106. alita_sdk/runtime/models/mcp_models.py +61 -0
  107. alita_sdk/runtime/skills/__init__.py +91 -0
  108. alita_sdk/runtime/skills/callbacks.py +498 -0
  109. alita_sdk/runtime/skills/discovery.py +540 -0
  110. alita_sdk/runtime/skills/executor.py +610 -0
  111. alita_sdk/runtime/skills/input_builder.py +371 -0
  112. alita_sdk/runtime/skills/models.py +330 -0
  113. alita_sdk/runtime/skills/registry.py +355 -0
  114. alita_sdk/runtime/skills/skill_runner.py +330 -0
  115. alita_sdk/runtime/toolkits/__init__.py +31 -0
  116. alita_sdk/runtime/toolkits/application.py +29 -10
  117. alita_sdk/runtime/toolkits/artifact.py +20 -11
  118. alita_sdk/runtime/toolkits/datasource.py +13 -6
  119. alita_sdk/runtime/toolkits/mcp.py +783 -0
  120. alita_sdk/runtime/toolkits/mcp_config.py +1048 -0
  121. alita_sdk/runtime/toolkits/planning.py +178 -0
  122. alita_sdk/runtime/toolkits/skill_router.py +238 -0
  123. alita_sdk/runtime/toolkits/subgraph.py +251 -6
  124. alita_sdk/runtime/toolkits/tools.py +356 -69
  125. alita_sdk/runtime/toolkits/vectorstore.py +11 -5
  126. alita_sdk/runtime/tools/__init__.py +10 -3
  127. alita_sdk/runtime/tools/application.py +27 -6
  128. alita_sdk/runtime/tools/artifact.py +511 -28
  129. alita_sdk/runtime/tools/data_analysis.py +183 -0
  130. alita_sdk/runtime/tools/function.py +67 -35
  131. alita_sdk/runtime/tools/graph.py +10 -4
  132. alita_sdk/runtime/tools/image_generation.py +148 -46
  133. alita_sdk/runtime/tools/llm.py +1003 -128
  134. alita_sdk/runtime/tools/loop.py +3 -1
  135. alita_sdk/runtime/tools/loop_output.py +3 -1
  136. alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
  137. alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
  138. alita_sdk/runtime/tools/mcp_server_tool.py +8 -5
  139. alita_sdk/runtime/tools/planning/__init__.py +36 -0
  140. alita_sdk/runtime/tools/planning/models.py +246 -0
  141. alita_sdk/runtime/tools/planning/wrapper.py +607 -0
  142. alita_sdk/runtime/tools/router.py +2 -4
  143. alita_sdk/runtime/tools/sandbox.py +65 -48
  144. alita_sdk/runtime/tools/skill_router.py +776 -0
  145. alita_sdk/runtime/tools/tool.py +3 -1
  146. alita_sdk/runtime/tools/vectorstore.py +9 -3
  147. alita_sdk/runtime/tools/vectorstore_base.py +70 -14
  148. alita_sdk/runtime/utils/AlitaCallback.py +137 -21
  149. alita_sdk/runtime/utils/constants.py +5 -1
  150. alita_sdk/runtime/utils/mcp_client.py +492 -0
  151. alita_sdk/runtime/utils/mcp_oauth.py +361 -0
  152. alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
  153. alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
  154. alita_sdk/runtime/utils/serialization.py +155 -0
  155. alita_sdk/runtime/utils/streamlit.py +40 -13
  156. alita_sdk/runtime/utils/toolkit_utils.py +30 -9
  157. alita_sdk/runtime/utils/utils.py +36 -0
  158. alita_sdk/tools/__init__.py +134 -35
  159. alita_sdk/tools/ado/repos/__init__.py +51 -32
  160. alita_sdk/tools/ado/repos/repos_wrapper.py +148 -89
  161. alita_sdk/tools/ado/test_plan/__init__.py +25 -9
  162. alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +23 -1
  163. alita_sdk/tools/ado/utils.py +1 -18
  164. alita_sdk/tools/ado/wiki/__init__.py +25 -12
  165. alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
  166. alita_sdk/tools/ado/work_item/__init__.py +26 -13
  167. alita_sdk/tools/ado/work_item/ado_wrapper.py +73 -11
  168. alita_sdk/tools/advanced_jira_mining/__init__.py +11 -8
  169. alita_sdk/tools/aws/delta_lake/__init__.py +13 -9
  170. alita_sdk/tools/aws/delta_lake/tool.py +5 -1
  171. alita_sdk/tools/azure_ai/search/__init__.py +11 -8
  172. alita_sdk/tools/azure_ai/search/api_wrapper.py +1 -1
  173. alita_sdk/tools/base/tool.py +5 -1
  174. alita_sdk/tools/base_indexer_toolkit.py +271 -84
  175. alita_sdk/tools/bitbucket/__init__.py +17 -11
  176. alita_sdk/tools/bitbucket/api_wrapper.py +59 -11
  177. alita_sdk/tools/bitbucket/cloud_api_wrapper.py +49 -35
  178. alita_sdk/tools/browser/__init__.py +5 -4
  179. alita_sdk/tools/carrier/__init__.py +5 -6
  180. alita_sdk/tools/carrier/backend_reports_tool.py +6 -6
  181. alita_sdk/tools/carrier/run_ui_test_tool.py +6 -6
  182. alita_sdk/tools/carrier/ui_reports_tool.py +5 -5
  183. alita_sdk/tools/chunkers/__init__.py +3 -1
  184. alita_sdk/tools/chunkers/code/treesitter/treesitter.py +37 -13
  185. alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
  186. alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
  187. alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
  188. alita_sdk/tools/chunkers/universal_chunker.py +270 -0
  189. alita_sdk/tools/cloud/aws/__init__.py +10 -7
  190. alita_sdk/tools/cloud/azure/__init__.py +10 -7
  191. alita_sdk/tools/cloud/gcp/__init__.py +10 -7
  192. alita_sdk/tools/cloud/k8s/__init__.py +10 -7
  193. alita_sdk/tools/code/linter/__init__.py +10 -8
  194. alita_sdk/tools/code/loaders/codesearcher.py +3 -2
  195. alita_sdk/tools/code/sonar/__init__.py +11 -8
  196. alita_sdk/tools/code_indexer_toolkit.py +82 -22
  197. alita_sdk/tools/confluence/__init__.py +22 -16
  198. alita_sdk/tools/confluence/api_wrapper.py +107 -30
  199. alita_sdk/tools/confluence/loader.py +14 -2
  200. alita_sdk/tools/custom_open_api/__init__.py +12 -5
  201. alita_sdk/tools/elastic/__init__.py +11 -8
  202. alita_sdk/tools/elitea_base.py +493 -30
  203. alita_sdk/tools/figma/__init__.py +58 -11
  204. alita_sdk/tools/figma/api_wrapper.py +1235 -143
  205. alita_sdk/tools/figma/figma_client.py +73 -0
  206. alita_sdk/tools/figma/toon_tools.py +2748 -0
  207. alita_sdk/tools/github/__init__.py +14 -15
  208. alita_sdk/tools/github/github_client.py +224 -100
  209. alita_sdk/tools/github/graphql_client_wrapper.py +119 -33
  210. alita_sdk/tools/github/schemas.py +14 -5
  211. alita_sdk/tools/github/tool.py +5 -1
  212. alita_sdk/tools/github/tool_prompts.py +9 -22
  213. alita_sdk/tools/gitlab/__init__.py +16 -11
  214. alita_sdk/tools/gitlab/api_wrapper.py +218 -48
  215. alita_sdk/tools/gitlab_org/__init__.py +10 -9
  216. alita_sdk/tools/gitlab_org/api_wrapper.py +63 -64
  217. alita_sdk/tools/google/bigquery/__init__.py +13 -12
  218. alita_sdk/tools/google/bigquery/tool.py +5 -1
  219. alita_sdk/tools/google_places/__init__.py +11 -8
  220. alita_sdk/tools/google_places/api_wrapper.py +1 -1
  221. alita_sdk/tools/jira/__init__.py +17 -10
  222. alita_sdk/tools/jira/api_wrapper.py +92 -41
  223. alita_sdk/tools/keycloak/__init__.py +11 -8
  224. alita_sdk/tools/localgit/__init__.py +9 -3
  225. alita_sdk/tools/localgit/local_git.py +62 -54
  226. alita_sdk/tools/localgit/tool.py +5 -1
  227. alita_sdk/tools/memory/__init__.py +12 -4
  228. alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
  229. alita_sdk/tools/ocr/__init__.py +11 -8
  230. alita_sdk/tools/openapi/__init__.py +491 -106
  231. alita_sdk/tools/openapi/api_wrapper.py +1368 -0
  232. alita_sdk/tools/openapi/tool.py +20 -0
  233. alita_sdk/tools/pandas/__init__.py +20 -12
  234. alita_sdk/tools/pandas/api_wrapper.py +38 -25
  235. alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
  236. alita_sdk/tools/postman/__init__.py +10 -9
  237. alita_sdk/tools/pptx/__init__.py +11 -10
  238. alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
  239. alita_sdk/tools/qtest/__init__.py +31 -11
  240. alita_sdk/tools/qtest/api_wrapper.py +2135 -86
  241. alita_sdk/tools/rally/__init__.py +10 -9
  242. alita_sdk/tools/rally/api_wrapper.py +1 -1
  243. alita_sdk/tools/report_portal/__init__.py +12 -8
  244. alita_sdk/tools/salesforce/__init__.py +10 -8
  245. alita_sdk/tools/servicenow/__init__.py +17 -15
  246. alita_sdk/tools/servicenow/api_wrapper.py +1 -1
  247. alita_sdk/tools/sharepoint/__init__.py +10 -7
  248. alita_sdk/tools/sharepoint/api_wrapper.py +129 -38
  249. alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
  250. alita_sdk/tools/sharepoint/utils.py +8 -2
  251. alita_sdk/tools/slack/__init__.py +10 -7
  252. alita_sdk/tools/slack/api_wrapper.py +2 -2
  253. alita_sdk/tools/sql/__init__.py +12 -9
  254. alita_sdk/tools/testio/__init__.py +10 -7
  255. alita_sdk/tools/testrail/__init__.py +11 -10
  256. alita_sdk/tools/testrail/api_wrapper.py +1 -1
  257. alita_sdk/tools/utils/__init__.py +9 -4
  258. alita_sdk/tools/utils/content_parser.py +103 -18
  259. alita_sdk/tools/utils/text_operations.py +410 -0
  260. alita_sdk/tools/utils/tool_prompts.py +79 -0
  261. alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +30 -13
  262. alita_sdk/tools/xray/__init__.py +13 -9
  263. alita_sdk/tools/yagmail/__init__.py +9 -3
  264. alita_sdk/tools/zephyr/__init__.py +10 -7
  265. alita_sdk/tools/zephyr_enterprise/__init__.py +11 -7
  266. alita_sdk/tools/zephyr_essential/__init__.py +10 -7
  267. alita_sdk/tools/zephyr_essential/api_wrapper.py +30 -13
  268. alita_sdk/tools/zephyr_essential/client.py +2 -2
  269. alita_sdk/tools/zephyr_scale/__init__.py +11 -8
  270. alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
  271. alita_sdk/tools/zephyr_squad/__init__.py +10 -7
  272. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +154 -8
  273. alita_sdk-0.3.627.dist-info/RECORD +468 -0
  274. alita_sdk-0.3.627.dist-info/entry_points.txt +2 -0
  275. alita_sdk-0.3.379.dist-info/RECORD +0 -360
  276. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
  277. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
  278. {alita_sdk-0.3.379.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,371 @@
1
+ """
2
+ Input preparation for different skill types.
3
+
4
+ This module handles the preparation of input data for skill execution,
5
+ ensuring that inputs are properly formatted for agent vs graph skill types.
6
+ """
7
+
8
+ import logging
9
+ from typing import Any, Dict, List, Optional
10
+
11
+ from .models import SkillMetadata, SkillType, SkillValidationError
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class SkillInputBuilder:
17
+ """
18
+ Service for building properly formatted inputs for different skill types.
19
+
20
+ This class handles the different input requirements for:
21
+ - Agent skills: variables, chat_history, and user input
22
+ - Graph skills: state variables with input field
23
+ """
24
+
25
+ @staticmethod
26
+ def prepare_input(
27
+ skill_metadata: SkillMetadata,
28
+ task: str,
29
+ context: Optional[Dict[str, Any]] = None,
30
+ chat_history: Optional[List[Dict[str, str]]] = None
31
+ ) -> Dict[str, Any]:
32
+ """
33
+ Prepare input data based on skill type.
34
+
35
+ Args:
36
+ skill_metadata: Metadata for the skill being executed.
37
+ task: The main task or user input for the skill.
38
+ context: Additional context data (variables for agents, state for graphs).
39
+ chat_history: Chat conversation history (for agents only).
40
+
41
+ Returns:
42
+ Properly formatted input dictionary for the skill type.
43
+
44
+ Raises:
45
+ SkillValidationError: If input preparation fails validation.
46
+ """
47
+ if skill_metadata.skill_type == SkillType.AGENT:
48
+ return SkillInputBuilder.prepare_agent_input(
49
+ skill_metadata, task, context, chat_history
50
+ )
51
+ else: # SkillType.GRAPH
52
+ return SkillInputBuilder.prepare_graph_input(
53
+ skill_metadata, task, context
54
+ )
55
+
56
+ @staticmethod
57
+ def prepare_agent_input(
58
+ skill_metadata: SkillMetadata,
59
+ task: str,
60
+ context: Optional[Dict[str, Any]] = None,
61
+ chat_history: Optional[List[Dict[str, str]]] = None
62
+ ) -> Dict[str, Any]:
63
+ """
64
+ Prepare input for agent-type skills.
65
+
66
+ Agent skills expect:
67
+ - variables: Skill-specific variables from context
68
+ - chat_history: Previous conversation messages
69
+ - input: Current user request/task
70
+
71
+ Args:
72
+ skill_metadata: Metadata for the agent skill.
73
+ task: User input/task for the agent.
74
+ context: Variables to pass to the agent.
75
+ chat_history: Conversation history.
76
+
77
+ Returns:
78
+ Agent input dictionary.
79
+
80
+ Raises:
81
+ SkillValidationError: If required inputs are missing or invalid.
82
+ """
83
+ logger.debug(f"Preparing agent input for skill: {skill_metadata.name}")
84
+
85
+ if not task:
86
+ raise SkillValidationError("Task is required for agent skills")
87
+
88
+ # Validate chat_history format if provided
89
+ if chat_history:
90
+ SkillInputBuilder._validate_chat_history(chat_history)
91
+
92
+ # Validate context variables against schema if defined
93
+ variables = context or {}
94
+ if skill_metadata.inputs.variables:
95
+ variables = SkillInputBuilder._validate_agent_variables(
96
+ variables, skill_metadata.inputs.variables
97
+ )
98
+
99
+ agent_input = {
100
+ 'variables': variables,
101
+ 'chat_history': chat_history or [],
102
+ 'input': task
103
+ }
104
+
105
+ logger.debug(f"Prepared agent input: variables={len(variables)}, "
106
+ f"chat_history={len(chat_history or [])}, task_length={len(task)}")
107
+
108
+ return agent_input
109
+
110
+ @staticmethod
111
+ def prepare_graph_input(
112
+ skill_metadata: SkillMetadata,
113
+ task: str,
114
+ context: Optional[Dict[str, Any]] = None
115
+ ) -> Dict[str, Any]:
116
+ """
117
+ Prepare input for graph-type skills.
118
+
119
+ Graph skills expect state variables with the task merged in
120
+ as the 'input' field.
121
+
122
+ Args:
123
+ skill_metadata: Metadata for the graph skill.
124
+ task: Task description to be included as 'input'.
125
+ context: State variables for the graph.
126
+
127
+ Returns:
128
+ Graph state input dictionary.
129
+
130
+ Raises:
131
+ SkillValidationError: If required inputs are missing or invalid.
132
+ """
133
+ logger.debug(f"Preparing graph input for skill: {skill_metadata.name}")
134
+
135
+ # Start with context (state variables)
136
+ state_vars = context.copy() if context else {}
137
+
138
+ # Add task as 'input' field (standard for graphs)
139
+ state_vars['input'] = task
140
+
141
+ # Validate state variables against schema if defined
142
+ if skill_metadata.inputs.state_variables:
143
+ state_vars = SkillInputBuilder._validate_graph_state_variables(
144
+ state_vars, skill_metadata.inputs.state_variables
145
+ )
146
+
147
+ logger.debug(f"Prepared graph input: {len(state_vars)} state variables")
148
+
149
+ return state_vars
150
+
151
+ @staticmethod
152
+ def _validate_chat_history(chat_history: List[Dict[str, str]]) -> None:
153
+ """
154
+ Validate chat history format.
155
+
156
+ Args:
157
+ chat_history: List of message dictionaries.
158
+
159
+ Raises:
160
+ SkillValidationError: If format is invalid.
161
+ """
162
+ if not isinstance(chat_history, list):
163
+ raise SkillValidationError("chat_history must be a list")
164
+
165
+ for i, message in enumerate(chat_history):
166
+ if not isinstance(message, dict):
167
+ raise SkillValidationError(f"chat_history[{i}] must be a dictionary")
168
+
169
+ if 'role' not in message:
170
+ raise SkillValidationError(f"chat_history[{i}] missing 'role' field")
171
+
172
+ if 'content' not in message:
173
+ raise SkillValidationError(f"chat_history[{i}] missing 'content' field")
174
+
175
+ if message['role'] not in ['user', 'assistant', 'system']:
176
+ logger.warning(f"Unusual role in chat_history[{i}]: {message['role']}")
177
+
178
+ @staticmethod
179
+ def _validate_agent_variables(
180
+ variables: Dict[str, Any],
181
+ variable_schema: Dict[str, Dict[str, Any]]
182
+ ) -> Dict[str, Any]:
183
+ """
184
+ Validate agent variables against schema.
185
+
186
+ Args:
187
+ variables: Variables to validate.
188
+ variable_schema: Schema definition for variables.
189
+
190
+ Returns:
191
+ Validated variables with defaults applied.
192
+
193
+ Raises:
194
+ SkillValidationError: If validation fails.
195
+ """
196
+ validated_vars = variables.copy()
197
+
198
+ # Check for required variables and apply defaults
199
+ for var_name, var_def in variable_schema.items():
200
+ if var_name not in validated_vars:
201
+ if 'default' in var_def:
202
+ validated_vars[var_name] = var_def['default']
203
+ logger.debug(f"Applied default for variable '{var_name}': {var_def['default']}")
204
+ elif var_def.get('required', False):
205
+ raise SkillValidationError(f"Required variable '{var_name}' not provided")
206
+
207
+ # Basic type validation (could be expanded)
208
+ if var_name in validated_vars:
209
+ expected_type = var_def.get('type')
210
+ if expected_type:
211
+ SkillInputBuilder._validate_variable_type(
212
+ var_name, validated_vars[var_name], expected_type
213
+ )
214
+
215
+ return validated_vars
216
+
217
+ @staticmethod
218
+ def _validate_graph_state_variables(
219
+ state_vars: Dict[str, Any],
220
+ state_schema: Dict[str, Dict[str, Any]]
221
+ ) -> Dict[str, Any]:
222
+ """
223
+ Validate graph state variables against schema.
224
+
225
+ Args:
226
+ state_vars: State variables to validate.
227
+ state_schema: Schema definition for state variables.
228
+
229
+ Returns:
230
+ Validated state variables with defaults applied.
231
+
232
+ Raises:
233
+ SkillValidationError: If validation fails.
234
+ """
235
+ validated_vars = state_vars.copy()
236
+
237
+ # Check for required state variables and apply defaults
238
+ for var_name, var_def in state_schema.items():
239
+ if var_name not in validated_vars:
240
+ if 'default' in var_def:
241
+ validated_vars[var_name] = var_def['default']
242
+ logger.debug(f"Applied default for state variable '{var_name}': {var_def['default']}")
243
+ elif var_def.get('required', False):
244
+ raise SkillValidationError(f"Required state variable '{var_name}' not provided")
245
+
246
+ # Basic type validation
247
+ if var_name in validated_vars:
248
+ expected_type = var_def.get('type')
249
+ if expected_type:
250
+ SkillInputBuilder._validate_variable_type(
251
+ var_name, validated_vars[var_name], expected_type
252
+ )
253
+
254
+ return validated_vars
255
+
256
+ @staticmethod
257
+ def _validate_variable_type(var_name: str, value: Any, expected_type: str) -> None:
258
+ """
259
+ Validate a variable against its expected type.
260
+
261
+ Args:
262
+ var_name: Name of the variable (for error messages).
263
+ value: Value to validate.
264
+ expected_type: Expected type string.
265
+
266
+ Raises:
267
+ SkillValidationError: If type validation fails.
268
+ """
269
+ # Simple type checking - could be made more sophisticated
270
+ type_map = {
271
+ 'str': str,
272
+ 'string': str,
273
+ 'int': int,
274
+ 'integer': int,
275
+ 'float': float,
276
+ 'number': (int, float),
277
+ 'bool': bool,
278
+ 'boolean': bool,
279
+ 'dict': dict,
280
+ 'list': list
281
+ }
282
+
283
+ expected_python_type = type_map.get(expected_type.lower())
284
+ if expected_python_type and not isinstance(value, expected_python_type):
285
+ raise SkillValidationError(
286
+ f"Variable '{var_name}' expected type {expected_type}, "
287
+ f"got {type(value).__name__}"
288
+ )
289
+
290
+ @staticmethod
291
+ def validate_skill_inputs(
292
+ skill_metadata: SkillMetadata,
293
+ task: str,
294
+ context: Optional[Dict[str, Any]] = None,
295
+ chat_history: Optional[List[Dict[str, str]]] = None
296
+ ) -> List[str]:
297
+ """
298
+ Validate inputs for a skill without preparing them.
299
+
300
+ This can be used to check if inputs are valid before execution.
301
+
302
+ Args:
303
+ skill_metadata: Metadata for the skill.
304
+ task: Task to validate.
305
+ context: Context data to validate.
306
+ chat_history: Chat history to validate (for agents).
307
+
308
+ Returns:
309
+ List of validation error messages (empty if all valid).
310
+ """
311
+ errors = []
312
+
313
+ try:
314
+ SkillInputBuilder.prepare_input(
315
+ skill_metadata, task, context, chat_history
316
+ )
317
+ except SkillValidationError as e:
318
+ errors.append(str(e))
319
+ except Exception as e:
320
+ errors.append(f"Unexpected validation error: {e}")
321
+
322
+ return errors
323
+
324
+ @staticmethod
325
+ def get_input_schema_summary(skill_metadata: SkillMetadata) -> Dict[str, Any]:
326
+ """
327
+ Get a human-readable summary of the skill's input schema.
328
+
329
+ Args:
330
+ skill_metadata: Metadata for the skill.
331
+
332
+ Returns:
333
+ Dictionary summarizing the input requirements.
334
+ """
335
+ summary = {
336
+ 'skill_name': skill_metadata.name,
337
+ 'skill_type': skill_metadata.skill_type.value,
338
+ 'requires_task': True # All skills require a task
339
+ }
340
+
341
+ if skill_metadata.skill_type == SkillType.AGENT:
342
+ summary.update({
343
+ 'supports_chat_history': True,
344
+ 'variables': {}
345
+ })
346
+
347
+ if skill_metadata.inputs.variables:
348
+ for var_name, var_def in skill_metadata.inputs.variables.items():
349
+ summary['variables'][var_name] = {
350
+ 'type': var_def.get('type', 'any'),
351
+ 'required': var_def.get('required', False),
352
+ 'description': var_def.get('description', ''),
353
+ 'default': var_def.get('default')
354
+ }
355
+
356
+ else: # GRAPH
357
+ summary.update({
358
+ 'supports_chat_history': False,
359
+ 'state_variables': {}
360
+ })
361
+
362
+ if skill_metadata.inputs.state_variables:
363
+ for var_name, var_def in skill_metadata.inputs.state_variables.items():
364
+ summary['state_variables'][var_name] = {
365
+ 'type': var_def.get('type', 'any'),
366
+ 'required': var_def.get('required', False),
367
+ 'description': var_def.get('description', ''),
368
+ 'default': var_def.get('default')
369
+ }
370
+
371
+ return summary
@@ -0,0 +1,330 @@
1
+ """
2
+ Core data models for the Skills Registry system.
3
+
4
+ This module defines the data structures used throughout the skills system,
5
+ including skill metadata, execution configuration, and result formats.
6
+ """
7
+
8
+ import logging
9
+ from dataclasses import dataclass
10
+ from enum import Enum
11
+ from pathlib import Path
12
+ from typing import Any, Dict, List, Literal, Optional
13
+
14
+ from pydantic import BaseModel, Field
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class SkillType(str, Enum):
20
+ """Skill execution architecture type."""
21
+ GRAPH = "graph"
22
+ AGENT = "agent"
23
+ PIPELINE = "pipeline"
24
+
25
+
26
+ class SkillSource(str, Enum):
27
+ """Source type for skill definitions."""
28
+ FILESYSTEM = "filesystem" # Local agent.md files
29
+ PLATFORM = "platform" # Platform-hosted agents/pipelines
30
+
31
+
32
+ class ExecutionMode(str, Enum):
33
+ """Skill execution isolation mode."""
34
+ SUBPROCESS = "subprocess"
35
+ REMOTE = "remote"
36
+
37
+
38
+ class SkillStatus(str, Enum):
39
+ """Skill execution status."""
40
+ SUCCESS = "success"
41
+ ERROR = "error"
42
+ TIMEOUT = "timeout"
43
+ RUNNING = "running"
44
+ PENDING = "pending"
45
+
46
+
47
+ class SkillEventType(str, Enum):
48
+ """Callback event types for skill execution."""
49
+ SKILL_START = "skill_start"
50
+ SKILL_END = "skill_end"
51
+ NODE_START = "node_start"
52
+ NODE_END = "node_end"
53
+ TOOL_START = "tool_start"
54
+ TOOL_END = "tool_end"
55
+ LLM_START = "llm_start"
56
+ LLM_END = "llm_end"
57
+ ERROR = "error"
58
+ PROGRESS = "progress"
59
+ CUSTOM_EVENT = "custom_event"
60
+
61
+
62
+ class ExecutionConfig(BaseModel):
63
+ """Configuration for skill execution."""
64
+
65
+ mode: ExecutionMode = ExecutionMode.SUBPROCESS
66
+ timeout: int = Field(default=300, description="Execution timeout in seconds")
67
+ working_directory: Optional[str] = Field(
68
+ default=None,
69
+ description="Working directory for skill execution"
70
+ )
71
+ environment: Dict[str, str] = Field(
72
+ default_factory=dict,
73
+ description="Environment variables for skill execution"
74
+ )
75
+ max_retries: int = Field(default=0, description="Maximum retry attempts")
76
+
77
+ class Config:
78
+ use_enum_values = True
79
+
80
+
81
+ class ResultsConfig(BaseModel):
82
+ """Configuration for skill result handling."""
83
+
84
+ format: Literal["text_with_links"] = "text_with_links"
85
+ output_files: List[str] = Field(
86
+ default_factory=list,
87
+ description="Expected output file patterns"
88
+ )
89
+ cleanup_policy: Literal["preserve", "cleanup"] = Field(
90
+ default="preserve",
91
+ description="Policy for cleaning up working directory"
92
+ )
93
+
94
+ class Config:
95
+ use_enum_values = True
96
+
97
+
98
+ class SkillInputSchema(BaseModel):
99
+ """Schema definition for skill inputs."""
100
+
101
+ # Common fields
102
+ description: Optional[str] = None
103
+
104
+ # Agent-specific inputs
105
+ variables: Optional[Dict[str, Dict[str, Any]]] = Field(
106
+ default=None,
107
+ description="Variable definitions for agent skills"
108
+ )
109
+ chat_history: Optional[Dict[str, Any]] = Field(
110
+ default=None,
111
+ description="Chat history schema for agent skills"
112
+ )
113
+ user_input: Optional[Dict[str, Any]] = Field(
114
+ default=None,
115
+ description="User input schema for agent skills"
116
+ )
117
+
118
+ # Graph-specific inputs
119
+ state_variables: Optional[Dict[str, Dict[str, Any]]] = Field(
120
+ default=None,
121
+ description="State variable definitions for graph skills"
122
+ )
123
+
124
+
125
+ class SkillOutputSchema(BaseModel):
126
+ """Schema definition for skill outputs."""
127
+
128
+ primary_output: Dict[str, Any] = Field(
129
+ default={"type": "text", "description": "Main result text"},
130
+ description="Primary text output schema"
131
+ )
132
+ generated_files: Dict[str, Any] = Field(
133
+ default={"type": "list[file_reference]", "description": "Created files"},
134
+ description="File references schema"
135
+ )
136
+ additional_outputs: Optional[Dict[str, Dict[str, Any]]] = Field(
137
+ default=None,
138
+ description="Additional skill-specific outputs"
139
+ )
140
+
141
+
142
+ class SkillMetadata(BaseModel):
143
+ """Complete metadata for a skill definition."""
144
+
145
+ # Core identification
146
+ name: str = Field(description="Unique skill identifier")
147
+ skill_type: SkillType = Field(description="Skill architecture type")
148
+ source: SkillSource = Field(description="Source type for skill definition")
149
+
150
+ # Filesystem-based skill fields
151
+ path: Optional[str] = Field(
152
+ default=None,
153
+ description="Directory path containing agent.md (for filesystem skills)"
154
+ )
155
+
156
+ # Platform-based skill fields
157
+ id: Optional[int] = Field(
158
+ default=None,
159
+ description="Platform ID (for platform-hosted skills)"
160
+ )
161
+ version_id: Optional[int] = Field(
162
+ default=None,
163
+ description="Platform version ID (for platform-hosted skills)"
164
+ )
165
+
166
+ # Descriptive metadata
167
+ description: str = Field(description="Human-readable skill description")
168
+ capabilities: List[str] = Field(
169
+ default_factory=list,
170
+ description="List of capabilities this skill provides"
171
+ )
172
+ tags: List[str] = Field(
173
+ default_factory=list,
174
+ description="Tags for categorization and filtering"
175
+ )
176
+ version: str = Field(default="1.0.0", description="Skill version")
177
+
178
+ # Configuration
179
+ execution: ExecutionConfig = Field(description="Execution configuration")
180
+ results: ResultsConfig = Field(description="Result handling configuration")
181
+
182
+ # Input/Output schemas
183
+ inputs: SkillInputSchema = Field(description="Input schema definition")
184
+ outputs: SkillOutputSchema = Field(description="Output schema definition")
185
+
186
+ # Type-specific configurations
187
+ # Graph-specific fields
188
+ state_schema: Optional[Dict[str, Any]] = Field(
189
+ default=None,
190
+ description="State schema for graph skills"
191
+ )
192
+ nodes: Optional[List[Dict[str, Any]]] = Field(
193
+ default=None,
194
+ description="Node definitions for graph skills"
195
+ )
196
+ graph_yaml: Optional[str] = Field(
197
+ default=None,
198
+ description="Complete YAML definition for graph skills"
199
+ )
200
+
201
+ # Agent-specific fields
202
+ system_prompt: Optional[str] = Field(
203
+ default=None,
204
+ description="System prompt for agent skills"
205
+ )
206
+ agent_type: Optional[str] = Field(
207
+ default=None,
208
+ description="Agent architecture type (react, xml, etc.)"
209
+ )
210
+ toolkits: Optional[List[Dict[str, Any]]] = Field(
211
+ default=None,
212
+ description="Toolkit configurations for agent skills"
213
+ )
214
+
215
+ # LLM configuration
216
+ model: Optional[str] = Field(default=None, description="Default LLM model")
217
+ temperature: Optional[float] = Field(default=None, description="LLM temperature")
218
+ max_tokens: Optional[int] = Field(default=None, description="Max tokens")
219
+
220
+ class Config:
221
+ use_enum_values = True
222
+
223
+
224
+ class SkillOutputFile(BaseModel):
225
+ """Reference to a file generated by skill execution."""
226
+
227
+ path: Path = Field(description="Path to the generated file")
228
+ description: str = Field(description="Human-readable file description")
229
+ file_type: str = Field(description="File type (json, markdown, csv, etc.)")
230
+ size_bytes: int = Field(description="File size in bytes")
231
+
232
+ def __str__(self) -> str:
233
+ """Format for LLM consumption."""
234
+ size_kb = self.size_bytes / 1024
235
+ if size_kb < 1:
236
+ size_str = f"{self.size_bytes} bytes"
237
+ else:
238
+ size_str = f"{size_kb:.1f}KB"
239
+
240
+ return f"[{self.description}]({self.path}) ({self.file_type}, {size_str})"
241
+
242
+
243
+ class SkillExecutionResult(BaseModel):
244
+ """Result of skill execution with text output and file references."""
245
+
246
+ # Execution metadata
247
+ skill_name: str = Field(description="Name of executed skill")
248
+ skill_type: SkillType = Field(description="Type of skill executed")
249
+ status: SkillStatus = Field(description="Execution status")
250
+ execution_mode: ExecutionMode = Field(description="Execution mode used")
251
+ execution_id: str = Field(description="Unique execution identifier")
252
+
253
+ # Results
254
+ output_text: str = Field(description="Primary text output for LLM consumption")
255
+ output_files: List[SkillOutputFile] = Field(
256
+ default_factory=list,
257
+ description="Generated files with descriptions"
258
+ )
259
+
260
+ # Execution details
261
+ duration: float = Field(description="Execution duration in seconds")
262
+ working_directory: Optional[Path] = Field(
263
+ default=None,
264
+ description="Working directory used for execution"
265
+ )
266
+
267
+ # Error information
268
+ error_details: Optional[str] = Field(
269
+ default=None,
270
+ description="Error details if status is ERROR"
271
+ )
272
+
273
+ # Additional metadata
274
+ metadata: Dict[str, Any] = Field(
275
+ default_factory=dict,
276
+ description="Additional execution metadata"
277
+ )
278
+
279
+ class Config:
280
+ use_enum_values = True
281
+
282
+ def format_for_llm(self) -> str:
283
+ """Format result as text suitable for LLM consumption."""
284
+ result = self.output_text
285
+
286
+ if self.output_files:
287
+ result += "\n\n**Generated Files:**\n"
288
+ for file in self.output_files:
289
+ result += f"- {file}\n"
290
+
291
+ if self.status == SkillStatus.ERROR and self.error_details:
292
+ result += f"\n\n**Error:** {self.error_details}"
293
+
294
+ return result
295
+
296
+
297
+ @dataclass
298
+ class SkillEvent:
299
+ """Event emitted during skill execution."""
300
+
301
+ event_type: SkillEventType
302
+ data: Dict[str, Any]
303
+ skill_name: str
304
+ execution_id: str
305
+ timestamp: float
306
+
307
+ def to_dict(self) -> Dict[str, Any]:
308
+ """Convert to dictionary for serialization."""
309
+ return {
310
+ "event_type": self.event_type.value,
311
+ "data": self.data,
312
+ "skill_name": self.skill_name,
313
+ "execution_id": self.execution_id,
314
+ "timestamp": self.timestamp
315
+ }
316
+
317
+
318
+ class SkillDiscoveryError(Exception):
319
+ """Exception raised during skill discovery."""
320
+ pass
321
+
322
+
323
+ class SkillValidationError(Exception):
324
+ """Exception raised during skill validation."""
325
+ pass
326
+
327
+
328
+ class SkillExecutionError(Exception):
329
+ """Exception raised during skill execution."""
330
+ pass