langchain-skilllite 0.1.0__tar.gz

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.
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SkillLite Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,203 @@
1
+ Metadata-Version: 2.4
2
+ Name: langchain-skilllite
3
+ Version: 0.1.0
4
+ Summary: LangChain integration for SkillLite - Lightweight sandboxed Python skill execution engine
5
+ Author-email: SkillLite Team <skilllite@example.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/EXboys/langchain-skilllite
8
+ Project-URL: Documentation, https://github.com/EXboys/langchain-skilllite#readme
9
+ Project-URL: Repository, https://github.com/EXboys/langchain-skilllite
10
+ Project-URL: Issues, https://github.com/EXboys/langchain-skilllite/issues
11
+ Project-URL: LangChain, https://python.langchain.com/
12
+ Project-URL: SkillLite, https://github.com/EXboys/skilllite
13
+ Keywords: langchain,skilllite,agent,tools,sandbox,llm,skills,python-execution
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: langchain-core>=0.3.0
31
+ Requires-Dist: skilllite>=0.1.1
32
+ Provides-Extra: langgraph
33
+ Requires-Dist: langgraph>=0.2.0; extra == "langgraph"
34
+ Provides-Extra: test
35
+ Requires-Dist: pytest>=7.0; extra == "test"
36
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
37
+ Requires-Dist: langchain-tests>=0.3.0; extra == "test"
38
+ Provides-Extra: dev
39
+ Requires-Dist: pytest>=7.0; extra == "dev"
40
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
41
+ Requires-Dist: langchain-tests>=0.3.0; extra == "dev"
42
+ Requires-Dist: black>=23.0; extra == "dev"
43
+ Requires-Dist: mypy>=1.0; extra == "dev"
44
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
45
+ Dynamic: license-file
46
+
47
+ # langchain-skilllite
48
+
49
+ [![PyPI version](https://badge.fury.io/py/langchain-skilllite.svg)](https://badge.fury.io/py/langchain-skilllite)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
51
+
52
+ LangChain integration for [SkillLite](https://github.com/EXboys/skilllite) - a lightweight sandboxed Python skill execution engine.
53
+
54
+ ## Features
55
+
56
+ - 🔒 **Sandboxed Execution** - All skills run in a Rust-based sandbox (skillbox)
57
+ - 📝 **Declarative Skills** - Define skills via SKILL.md, no Python wrappers needed
58
+ - 🔍 **Security Scanning** - Pre-execution code analysis for dangerous operations
59
+ - ✅ **Confirmation Callbacks** - User approval for high-severity security issues
60
+ - ⚡ **Async Support** - Full async support for LangGraph agents
61
+
62
+ ## Installation
63
+
64
+ ```bash
65
+ pip install langchain-skilllite
66
+ ```
67
+
68
+ This will also install the required dependencies:
69
+ - `langchain-core>=0.3.0`
70
+ - `skilllite>=0.1.1`
71
+
72
+ ## Quick Start
73
+
74
+ ```python
75
+ from langchain_skilllite import SkillLiteToolkit
76
+ from langchain_openai import ChatOpenAI
77
+ from langgraph.prebuilt import create_react_agent
78
+
79
+ # Load all skills from a directory as LangChain tools
80
+ tools = SkillLiteToolkit.from_directory("./skills")
81
+
82
+ # Create a LangGraph agent
83
+ agent = create_react_agent(ChatOpenAI(model="gpt-4"), tools)
84
+
85
+ # Run the agent
86
+ result = agent.invoke({
87
+ "messages": [("user", "Calculate 15 + 27 using the calculator skill")]
88
+ })
89
+ ```
90
+
91
+ ## Usage
92
+
93
+ ### Basic Usage with SkillManager
94
+
95
+ ```python
96
+ from skilllite import SkillManager
97
+ from langchain_skilllite import SkillLiteToolkit
98
+
99
+ # Create a SkillManager
100
+ manager = SkillManager(skills_dir="./skills")
101
+
102
+ # Convert all skills to LangChain tools
103
+ tools = SkillLiteToolkit.from_manager(manager)
104
+
105
+ # Or select specific skills
106
+ tools = SkillLiteToolkit.from_manager(
107
+ manager,
108
+ skill_names=["calculator", "web_search"],
109
+ allow_network=True,
110
+ timeout=60
111
+ )
112
+ ```
113
+
114
+ ### Security Levels
115
+
116
+ SkillLite supports three sandbox security levels:
117
+
118
+ | Level | Description |
119
+ |-------|-------------|
120
+ | 1 | No sandbox - direct execution (fastest, least secure) |
121
+ | 2 | Sandbox isolation only |
122
+ | 3 | Sandbox + security scanning (default, most secure) |
123
+
124
+ ```python
125
+ # Level 3 with confirmation callback for high-severity issues
126
+ def confirm_execution(report: str, scan_id: str) -> bool:
127
+ print(report)
128
+ return input("Proceed? [y/N]: ").lower() == 'y'
129
+
130
+ tools = SkillLiteToolkit.from_directory(
131
+ "./skills",
132
+ sandbox_level=3,
133
+ confirmation_callback=confirm_execution
134
+ )
135
+ ```
136
+
137
+ ### Async Confirmation (for LangGraph)
138
+
139
+ ```python
140
+ import asyncio
141
+
142
+ async def async_confirm(report: str, scan_id: str) -> bool:
143
+ print(report)
144
+ # In a real app, this might be a UI prompt
145
+ return True
146
+
147
+ tools = SkillLiteToolkit.from_directory(
148
+ "./skills",
149
+ sandbox_level=3,
150
+ async_confirmation_callback=async_confirm
151
+ )
152
+ ```
153
+
154
+ ### Callback Handler for Monitoring
155
+
156
+ ```python
157
+ from langchain_skilllite import SkillLiteCallbackHandler
158
+
159
+ handler = SkillLiteCallbackHandler(verbose=True)
160
+
161
+ # Use with agent
162
+ result = agent.invoke(
163
+ {"messages": [("user", "Run my skill")]},
164
+ config={"callbacks": [handler]}
165
+ )
166
+
167
+ # Get execution summary
168
+ print(handler.get_execution_summary())
169
+ ```
170
+
171
+ ## API Reference
172
+
173
+ ### SkillLiteTool
174
+
175
+ LangChain `BaseTool` adapter for a single SkillLite skill.
176
+
177
+ ### SkillLiteToolkit
178
+
179
+ Factory class for creating multiple `SkillLiteTool` instances.
180
+
181
+ - `from_manager(manager, ...)` - Create tools from a SkillManager
182
+ - `from_directory(skills_dir, ...)` - Create tools from a skills directory
183
+
184
+ ### SkillLiteCallbackHandler
185
+
186
+ LangChain callback handler for monitoring skill execution.
187
+
188
+ ## Requirements
189
+
190
+ - Python >= 3.9
191
+ - langchain-core >= 0.3.0
192
+ - skilllite >= 0.1.1
193
+
194
+ ## License
195
+
196
+ MIT License - see [LICENSE](LICENSE) for details.
197
+
198
+ ## Links
199
+
200
+ - [SkillLite Repository](https://github.com/EXboys/skilllite)
201
+ - [LangChain Documentation](https://python.langchain.com/)
202
+ - [LangGraph Documentation](https://langchain-ai.github.io/langgraph/)
203
+
@@ -0,0 +1,157 @@
1
+ # langchain-skilllite
2
+
3
+ [![PyPI version](https://badge.fury.io/py/langchain-skilllite.svg)](https://badge.fury.io/py/langchain-skilllite)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ LangChain integration for [SkillLite](https://github.com/EXboys/skilllite) - a lightweight sandboxed Python skill execution engine.
7
+
8
+ ## Features
9
+
10
+ - 🔒 **Sandboxed Execution** - All skills run in a Rust-based sandbox (skillbox)
11
+ - 📝 **Declarative Skills** - Define skills via SKILL.md, no Python wrappers needed
12
+ - 🔍 **Security Scanning** - Pre-execution code analysis for dangerous operations
13
+ - ✅ **Confirmation Callbacks** - User approval for high-severity security issues
14
+ - ⚡ **Async Support** - Full async support for LangGraph agents
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ pip install langchain-skilllite
20
+ ```
21
+
22
+ This will also install the required dependencies:
23
+ - `langchain-core>=0.3.0`
24
+ - `skilllite>=0.1.1`
25
+
26
+ ## Quick Start
27
+
28
+ ```python
29
+ from langchain_skilllite import SkillLiteToolkit
30
+ from langchain_openai import ChatOpenAI
31
+ from langgraph.prebuilt import create_react_agent
32
+
33
+ # Load all skills from a directory as LangChain tools
34
+ tools = SkillLiteToolkit.from_directory("./skills")
35
+
36
+ # Create a LangGraph agent
37
+ agent = create_react_agent(ChatOpenAI(model="gpt-4"), tools)
38
+
39
+ # Run the agent
40
+ result = agent.invoke({
41
+ "messages": [("user", "Calculate 15 + 27 using the calculator skill")]
42
+ })
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ ### Basic Usage with SkillManager
48
+
49
+ ```python
50
+ from skilllite import SkillManager
51
+ from langchain_skilllite import SkillLiteToolkit
52
+
53
+ # Create a SkillManager
54
+ manager = SkillManager(skills_dir="./skills")
55
+
56
+ # Convert all skills to LangChain tools
57
+ tools = SkillLiteToolkit.from_manager(manager)
58
+
59
+ # Or select specific skills
60
+ tools = SkillLiteToolkit.from_manager(
61
+ manager,
62
+ skill_names=["calculator", "web_search"],
63
+ allow_network=True,
64
+ timeout=60
65
+ )
66
+ ```
67
+
68
+ ### Security Levels
69
+
70
+ SkillLite supports three sandbox security levels:
71
+
72
+ | Level | Description |
73
+ |-------|-------------|
74
+ | 1 | No sandbox - direct execution (fastest, least secure) |
75
+ | 2 | Sandbox isolation only |
76
+ | 3 | Sandbox + security scanning (default, most secure) |
77
+
78
+ ```python
79
+ # Level 3 with confirmation callback for high-severity issues
80
+ def confirm_execution(report: str, scan_id: str) -> bool:
81
+ print(report)
82
+ return input("Proceed? [y/N]: ").lower() == 'y'
83
+
84
+ tools = SkillLiteToolkit.from_directory(
85
+ "./skills",
86
+ sandbox_level=3,
87
+ confirmation_callback=confirm_execution
88
+ )
89
+ ```
90
+
91
+ ### Async Confirmation (for LangGraph)
92
+
93
+ ```python
94
+ import asyncio
95
+
96
+ async def async_confirm(report: str, scan_id: str) -> bool:
97
+ print(report)
98
+ # In a real app, this might be a UI prompt
99
+ return True
100
+
101
+ tools = SkillLiteToolkit.from_directory(
102
+ "./skills",
103
+ sandbox_level=3,
104
+ async_confirmation_callback=async_confirm
105
+ )
106
+ ```
107
+
108
+ ### Callback Handler for Monitoring
109
+
110
+ ```python
111
+ from langchain_skilllite import SkillLiteCallbackHandler
112
+
113
+ handler = SkillLiteCallbackHandler(verbose=True)
114
+
115
+ # Use with agent
116
+ result = agent.invoke(
117
+ {"messages": [("user", "Run my skill")]},
118
+ config={"callbacks": [handler]}
119
+ )
120
+
121
+ # Get execution summary
122
+ print(handler.get_execution_summary())
123
+ ```
124
+
125
+ ## API Reference
126
+
127
+ ### SkillLiteTool
128
+
129
+ LangChain `BaseTool` adapter for a single SkillLite skill.
130
+
131
+ ### SkillLiteToolkit
132
+
133
+ Factory class for creating multiple `SkillLiteTool` instances.
134
+
135
+ - `from_manager(manager, ...)` - Create tools from a SkillManager
136
+ - `from_directory(skills_dir, ...)` - Create tools from a skills directory
137
+
138
+ ### SkillLiteCallbackHandler
139
+
140
+ LangChain callback handler for monitoring skill execution.
141
+
142
+ ## Requirements
143
+
144
+ - Python >= 3.9
145
+ - langchain-core >= 0.3.0
146
+ - skilllite >= 0.1.1
147
+
148
+ ## License
149
+
150
+ MIT License - see [LICENSE](LICENSE) for details.
151
+
152
+ ## Links
153
+
154
+ - [SkillLite Repository](https://github.com/EXboys/skilllite)
155
+ - [LangChain Documentation](https://python.langchain.com/)
156
+ - [LangGraph Documentation](https://langchain-ai.github.io/langgraph/)
157
+
@@ -0,0 +1,54 @@
1
+ """
2
+ LangChain integration for SkillLite.
3
+
4
+ This package provides LangChain-compatible tools for executing SkillLite skills
5
+ in a sandboxed environment. It acts as a thin adapter layer on top of the
6
+ skilllite core package.
7
+
8
+ Key Features:
9
+ - SkillLiteTool: LangChain BaseTool adapter for individual skills
10
+ - SkillLiteToolkit: Convenient toolkit for loading multiple skills
11
+ - Security scanning and confirmation callbacks for sandbox level 3
12
+ - Full async support for LangGraph agents
13
+
14
+ Installation:
15
+ pip install langchain-skilllite
16
+
17
+ Quick Start:
18
+ ```python
19
+ from langchain_skilllite import SkillLiteToolkit
20
+ from langchain_openai import ChatOpenAI
21
+ from langgraph.prebuilt import create_react_agent
22
+
23
+ # Load skills as LangChain tools
24
+ tools = SkillLiteToolkit.from_directory("./skills")
25
+
26
+ # Use with any LangChain agent
27
+ agent = create_react_agent(ChatOpenAI(), tools)
28
+ result = agent.invoke({"messages": [("user", "Run my skill")]})
29
+ ```
30
+
31
+ For more information, see:
32
+ - SkillLite: https://github.com/EXboys/skilllite
33
+ - LangChain: https://python.langchain.com/
34
+ """
35
+
36
+ from langchain_skilllite.tools import (
37
+ SkillLiteTool,
38
+ SkillLiteToolkit,
39
+ )
40
+ from langchain_skilllite.callbacks import (
41
+ SkillLiteCallbackHandler,
42
+ )
43
+ from langchain_skilllite._version import __version__
44
+
45
+ __all__ = [
46
+ # Core Tools
47
+ "SkillLiteTool",
48
+ "SkillLiteToolkit",
49
+ # Callbacks
50
+ "SkillLiteCallbackHandler",
51
+ # Version
52
+ "__version__",
53
+ ]
54
+
@@ -0,0 +1,4 @@
1
+ """Version information for langchain-skilllite."""
2
+
3
+ __version__ = "0.1.0"
4
+
@@ -0,0 +1,166 @@
1
+ """
2
+ LangChain callback handlers for SkillLite.
3
+
4
+ This module provides callback handlers for integrating SkillLite
5
+ with LangChain's callback system for logging, tracing, and monitoring.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import logging
11
+ from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union
12
+ from uuid import UUID
13
+
14
+ from langchain_core.callbacks import BaseCallbackHandler
15
+ from langchain_core.outputs import LLMResult
16
+
17
+ if TYPE_CHECKING:
18
+ from langchain_core.agents import AgentAction, AgentFinish
19
+ from langchain_core.messages import BaseMessage
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class SkillLiteCallbackHandler(BaseCallbackHandler):
25
+ """
26
+ LangChain callback handler for SkillLite skill execution.
27
+
28
+ This handler logs skill execution events and can be used for
29
+ monitoring, debugging, and auditing SkillLite tool usage.
30
+
31
+ Usage:
32
+ from langchain_skilllite import SkillLiteCallbackHandler
33
+
34
+ handler = SkillLiteCallbackHandler(verbose=True)
35
+
36
+ # Use with LangChain agent
37
+ agent.invoke({"input": "..."}, config={"callbacks": [handler]})
38
+
39
+ Attributes:
40
+ verbose: Whether to print execution details
41
+ execution_log: List of execution events
42
+ """
43
+
44
+ def __init__(
45
+ self,
46
+ verbose: bool = False,
47
+ log_level: int = logging.INFO,
48
+ ):
49
+ """
50
+ Initialize the callback handler.
51
+
52
+ Args:
53
+ verbose: If True, print execution details to stdout
54
+ log_level: Logging level for internal logging
55
+ """
56
+ super().__init__()
57
+ self.verbose = verbose
58
+ self.log_level = log_level
59
+ self.execution_log: List[Dict[str, Any]] = []
60
+ self._current_tool: Optional[str] = None
61
+
62
+ def on_tool_start(
63
+ self,
64
+ serialized: Dict[str, Any],
65
+ input_str: str,
66
+ *,
67
+ run_id: UUID,
68
+ parent_run_id: Optional[UUID] = None,
69
+ tags: Optional[List[str]] = None,
70
+ metadata: Optional[Dict[str, Any]] = None,
71
+ inputs: Optional[Dict[str, Any]] = None,
72
+ **kwargs: Any,
73
+ ) -> None:
74
+ """Called when a tool starts running."""
75
+ tool_name = serialized.get("name", "unknown")
76
+ self._current_tool = tool_name
77
+
78
+ event = {
79
+ "event": "tool_start",
80
+ "tool_name": tool_name,
81
+ "run_id": str(run_id),
82
+ "input": input_str[:200] if input_str else None,
83
+ }
84
+ self.execution_log.append(event)
85
+
86
+ if self.verbose:
87
+ print(f"🔧 [SkillLite] Starting tool: {tool_name}")
88
+ logger.log(self.log_level, f"Tool started: {tool_name}")
89
+
90
+ def on_tool_end(
91
+ self,
92
+ output: Any,
93
+ *,
94
+ run_id: UUID,
95
+ parent_run_id: Optional[UUID] = None,
96
+ **kwargs: Any,
97
+ ) -> None:
98
+ """Called when a tool finishes."""
99
+ # Handle different output types (str, ToolMessage, etc.)
100
+ if isinstance(output, str):
101
+ output_preview = output[:200] if output else None
102
+ elif hasattr(output, "content"):
103
+ # ToolMessage or similar object
104
+ content = output.content
105
+ output_preview = content[:200] if isinstance(content, str) and content else str(content)[:200]
106
+ else:
107
+ output_preview = str(output)[:200] if output else None
108
+
109
+ event = {
110
+ "event": "tool_end",
111
+ "tool_name": self._current_tool,
112
+ "run_id": str(run_id),
113
+ "output_preview": output_preview,
114
+ "success": True,
115
+ }
116
+ self.execution_log.append(event)
117
+
118
+ if self.verbose:
119
+ print(f"✅ [SkillLite] Tool completed: {self._current_tool}")
120
+ logger.log(self.log_level, f"Tool completed: {self._current_tool}")
121
+
122
+ self._current_tool = None
123
+
124
+ def on_tool_error(
125
+ self,
126
+ error: BaseException,
127
+ *,
128
+ run_id: UUID,
129
+ parent_run_id: Optional[UUID] = None,
130
+ **kwargs: Any,
131
+ ) -> None:
132
+ """Called when a tool errors."""
133
+ event = {
134
+ "event": "tool_error",
135
+ "tool_name": self._current_tool,
136
+ "run_id": str(run_id),
137
+ "error": str(error),
138
+ "success": False,
139
+ }
140
+ self.execution_log.append(event)
141
+
142
+ if self.verbose:
143
+ print(f"❌ [SkillLite] Tool error: {self._current_tool} - {error}")
144
+ logger.error(f"Tool error: {self._current_tool} - {error}")
145
+
146
+ self._current_tool = None
147
+
148
+ def get_execution_summary(self) -> Dict[str, Any]:
149
+ """Get a summary of all execution events."""
150
+ total = len(self.execution_log)
151
+ tool_starts = sum(1 for e in self.execution_log if e["event"] == "tool_start")
152
+ tool_ends = sum(1 for e in self.execution_log if e["event"] == "tool_end")
153
+ tool_errors = sum(1 for e in self.execution_log if e["event"] == "tool_error")
154
+
155
+ return {
156
+ "total_events": total,
157
+ "tool_executions": tool_starts,
158
+ "successful": tool_ends,
159
+ "errors": tool_errors,
160
+ "success_rate": tool_ends / tool_starts if tool_starts > 0 else 0,
161
+ }
162
+
163
+ def clear_log(self) -> None:
164
+ """Clear the execution log."""
165
+ self.execution_log.clear()
166
+