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,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
|