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.
- skilllite-0.1.0/LICENSE +21 -0
- skilllite-0.1.0/MANIFEST.in +4 -0
- skilllite-0.1.0/PKG-INFO +293 -0
- skilllite-0.1.0/README.md +247 -0
- skilllite-0.1.0/pyproject.toml +87 -0
- skilllite-0.1.0/setup.cfg +4 -0
- skilllite-0.1.0/setup.py +10 -0
- skilllite-0.1.0/skilllite/__init__.py +159 -0
- skilllite-0.1.0/skilllite/analyzer.py +391 -0
- skilllite-0.1.0/skilllite/builtin_tools.py +240 -0
- skilllite-0.1.0/skilllite/cli.py +217 -0
- skilllite-0.1.0/skilllite/core/__init__.py +65 -0
- skilllite-0.1.0/skilllite/core/executor.py +182 -0
- skilllite-0.1.0/skilllite/core/handler.py +332 -0
- skilllite-0.1.0/skilllite/core/loops.py +770 -0
- skilllite-0.1.0/skilllite/core/manager.py +507 -0
- skilllite-0.1.0/skilllite/core/metadata.py +338 -0
- skilllite-0.1.0/skilllite/core/prompt_builder.py +321 -0
- skilllite-0.1.0/skilllite/core/registry.py +185 -0
- skilllite-0.1.0/skilllite/core/skill_info.py +181 -0
- skilllite-0.1.0/skilllite/core/tool_builder.py +338 -0
- skilllite-0.1.0/skilllite/core/tools.py +253 -0
- skilllite-0.1.0/skilllite/mcp/__init__.py +45 -0
- skilllite-0.1.0/skilllite/mcp/server.py +734 -0
- skilllite-0.1.0/skilllite/quick.py +420 -0
- skilllite-0.1.0/skilllite/sandbox/__init__.py +36 -0
- skilllite-0.1.0/skilllite/sandbox/base.py +93 -0
- skilllite-0.1.0/skilllite/sandbox/config.py +229 -0
- skilllite-0.1.0/skilllite/sandbox/skillbox/__init__.py +44 -0
- skilllite-0.1.0/skilllite/sandbox/skillbox/binary.py +421 -0
- skilllite-0.1.0/skilllite/sandbox/skillbox/executor.py +608 -0
- skilllite-0.1.0/skilllite/sandbox/utils.py +77 -0
- skilllite-0.1.0/skilllite/validation.py +137 -0
- skilllite-0.1.0/skilllite.egg-info/PKG-INFO +293 -0
- skilllite-0.1.0/skilllite.egg-info/SOURCES.txt +37 -0
- skilllite-0.1.0/skilllite.egg-info/dependency_links.txt +1 -0
- skilllite-0.1.0/skilllite.egg-info/entry_points.txt +3 -0
- skilllite-0.1.0/skilllite.egg-info/requires.txt +22 -0
- skilllite-0.1.0/skilllite.egg-info/top_level.txt +1 -0
skilllite-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 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.
|
skilllite-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skilllite
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A lightweight Skills execution engine with LLM integration for LLM agents
|
|
5
|
+
Author-email: SkillLite Team <skilllite@example.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/EXboys/skilllite
|
|
8
|
+
Project-URL: Documentation, https://github.com/EXboys/skilllite#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/EXboys/skilllite
|
|
10
|
+
Project-URL: Issues, https://github.com/EXboys/skilllite/issues
|
|
11
|
+
Keywords: agent,skills,llm,claude,openai,sandbox,tools
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Provides-Extra: openai
|
|
30
|
+
Requires-Dist: openai>=1.0.0; extra == "openai"
|
|
31
|
+
Provides-Extra: anthropic
|
|
32
|
+
Requires-Dist: anthropic>=0.18.0; extra == "anthropic"
|
|
33
|
+
Provides-Extra: mcp
|
|
34
|
+
Requires-Dist: mcp>=1.0.0; extra == "mcp"
|
|
35
|
+
Provides-Extra: all
|
|
36
|
+
Requires-Dist: openai>=1.0.0; extra == "all"
|
|
37
|
+
Requires-Dist: anthropic>=0.18.0; extra == "all"
|
|
38
|
+
Requires-Dist: mcp>=1.0.0; extra == "all"
|
|
39
|
+
Provides-Extra: dev
|
|
40
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
41
|
+
Requires-Dist: pytest-asyncio>=0.21.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
|
+
# SkillLite Python SDK
|
|
48
|
+
|
|
49
|
+
A Python SDK for the SkillLite execution engine, using **OpenAI-compatible API format** as the unified interface.
|
|
50
|
+
|
|
51
|
+
## Supported Providers
|
|
52
|
+
|
|
53
|
+
Works with any OpenAI-compatible LLM provider:
|
|
54
|
+
- **OpenAI** (GPT-4, GPT-3.5, etc.)
|
|
55
|
+
- **Azure OpenAI**
|
|
56
|
+
- **Anthropic Claude** (via OpenAI-compatible endpoint or native)
|
|
57
|
+
- **Google Gemini** (via OpenAI-compatible endpoint)
|
|
58
|
+
- **Local models** (Ollama, vLLM, LMStudio, etc.)
|
|
59
|
+
- **DeepSeek, Qwen, Moonshot, Zhipu**, and other providers
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install skilllite
|
|
65
|
+
|
|
66
|
+
# With OpenAI SDK (recommended, works with all compatible providers)
|
|
67
|
+
pip install skilllite[openai]
|
|
68
|
+
|
|
69
|
+
# With Anthropic SDK (for Claude's native API)
|
|
70
|
+
pip install skilllite[anthropic]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Prerequisites
|
|
74
|
+
|
|
75
|
+
You need to have the `skillbox` binary installed:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# From the skillbox directory
|
|
79
|
+
cargo install --path .
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Quick Start
|
|
83
|
+
|
|
84
|
+
### Basic Usage (Universal - Works with Any Provider)
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from openai import OpenAI
|
|
88
|
+
from skilllite import SkillManager
|
|
89
|
+
|
|
90
|
+
# Works with ANY OpenAI-compatible provider
|
|
91
|
+
# Just change base_url and api_key for different providers:
|
|
92
|
+
|
|
93
|
+
# OpenAI
|
|
94
|
+
client = OpenAI()
|
|
95
|
+
|
|
96
|
+
# Ollama (local)
|
|
97
|
+
# client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
|
|
98
|
+
|
|
99
|
+
# DeepSeek
|
|
100
|
+
# client = OpenAI(base_url="https://api.deepseek.com/v1", api_key="...")
|
|
101
|
+
|
|
102
|
+
# Qwen (通义千问)
|
|
103
|
+
# client = OpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="...")
|
|
104
|
+
|
|
105
|
+
# Moonshot (月之暗面)
|
|
106
|
+
# client = OpenAI(base_url="https://api.moonshot.cn/v1", api_key="...")
|
|
107
|
+
|
|
108
|
+
# Initialize SkillManager
|
|
109
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
110
|
+
|
|
111
|
+
# Get tools (OpenAI-compatible format - works with all providers)
|
|
112
|
+
tools = manager.get_tools()
|
|
113
|
+
|
|
114
|
+
# Call any OpenAI-compatible API
|
|
115
|
+
response = client.chat.completions.create(
|
|
116
|
+
model="gpt-4", # or "llama2", "deepseek-chat", "qwen-turbo", etc.
|
|
117
|
+
tools=tools,
|
|
118
|
+
messages=[{"role": "user", "content": "Please help me with..."}]
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Handle tool calls (same code works for all providers!)
|
|
122
|
+
if response.choices[0].message.tool_calls:
|
|
123
|
+
tool_results = manager.handle_tool_calls(response)
|
|
124
|
+
|
|
125
|
+
# Continue conversation with results
|
|
126
|
+
messages = [
|
|
127
|
+
{"role": "user", "content": "Please help me with..."},
|
|
128
|
+
response.choices[0].message,
|
|
129
|
+
*[r.to_openai_format() for r in tool_results]
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
follow_up = client.chat.completions.create(
|
|
133
|
+
model="gpt-4",
|
|
134
|
+
tools=tools,
|
|
135
|
+
messages=messages
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Agentic Loop (Automatic Multi-turn Tool Execution)
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from openai import OpenAI
|
|
143
|
+
from skilllite import SkillManager
|
|
144
|
+
|
|
145
|
+
# Works with any provider
|
|
146
|
+
client = OpenAI() # or OpenAI(base_url="...", api_key="...")
|
|
147
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
148
|
+
|
|
149
|
+
# Create an agentic loop
|
|
150
|
+
loop = manager.create_agentic_loop(
|
|
151
|
+
client=client,
|
|
152
|
+
model="gpt-4",
|
|
153
|
+
system_prompt="You are a helpful assistant with access to various skills.",
|
|
154
|
+
max_iterations=10,
|
|
155
|
+
temperature=0.7 # Additional kwargs passed to chat.completions.create()
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Run until completion - handles multiple tool calls automatically
|
|
159
|
+
final_response = loop.run("Please analyze this data and generate a report.")
|
|
160
|
+
print(final_response.choices[0].message.content)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Claude Native API (Optional)
|
|
164
|
+
|
|
165
|
+
If you prefer using Claude's native API directly:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
import anthropic
|
|
169
|
+
from skilllite import SkillManager
|
|
170
|
+
|
|
171
|
+
client = anthropic.Anthropic()
|
|
172
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
173
|
+
|
|
174
|
+
# Use Claude-specific methods
|
|
175
|
+
tools = manager.get_tools_for_claude_native()
|
|
176
|
+
response = client.messages.create(
|
|
177
|
+
model="claude-sonnet-4-20250514",
|
|
178
|
+
max_tokens=4096,
|
|
179
|
+
tools=tools,
|
|
180
|
+
messages=[{"role": "user", "content": "..."}]
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
if response.stop_reason == "tool_use":
|
|
184
|
+
results = manager.handle_tool_calls_claude_native(response)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Creating Skills
|
|
188
|
+
|
|
189
|
+
Skills are defined in directories with a `SKILL.md` file:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
my_skills/
|
|
193
|
+
├── web-search/
|
|
194
|
+
│ ├── SKILL.md # Metadata and docs (includes dependency declaration)
|
|
195
|
+
│ └── scripts/
|
|
196
|
+
│ └── main.py
|
|
197
|
+
└── calculator/
|
|
198
|
+
├── SKILL.md
|
|
199
|
+
└── scripts/
|
|
200
|
+
└── main.py
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
> **Note**: Python dependencies are declared in the `compatibility` field of `SKILL.md`, not in a separate `requirements.txt` file.
|
|
204
|
+
|
|
205
|
+
### SKILL.md Format
|
|
206
|
+
|
|
207
|
+
```markdown
|
|
208
|
+
---
|
|
209
|
+
name: web-search
|
|
210
|
+
description: Search the web for information
|
|
211
|
+
compatibility: Requires Python 3.x with requests library, network access
|
|
212
|
+
license: MIT
|
|
213
|
+
metadata:
|
|
214
|
+
author: example-org
|
|
215
|
+
version: "1.0"
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
# Web Search Skill
|
|
219
|
+
|
|
220
|
+
This skill searches the web for information.
|
|
221
|
+
|
|
222
|
+
## Input Parameters
|
|
223
|
+
|
|
224
|
+
- `query`: The search query (required)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The `compatibility` field is used to:
|
|
228
|
+
- Detect language (Python/Node/Bash)
|
|
229
|
+
- Enable network access (keywords: network, internet, http, api, web)
|
|
230
|
+
- Auto-install dependencies (known packages like requests, pandas, axios, etc.)
|
|
231
|
+
|
|
232
|
+
### Skill Entry Point
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
# main.py
|
|
236
|
+
import json
|
|
237
|
+
import sys
|
|
238
|
+
|
|
239
|
+
def main():
|
|
240
|
+
# Read input from stdin
|
|
241
|
+
input_data = json.loads(sys.stdin.read())
|
|
242
|
+
|
|
243
|
+
# Process the input
|
|
244
|
+
query = input_data.get("query", "")
|
|
245
|
+
|
|
246
|
+
# Do something...
|
|
247
|
+
result = {"results": [f"Result for: {query}"]}
|
|
248
|
+
|
|
249
|
+
# Output JSON to stdout
|
|
250
|
+
print(json.dumps(result))
|
|
251
|
+
|
|
252
|
+
if __name__ == "__main__":
|
|
253
|
+
main()
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## API Reference
|
|
257
|
+
|
|
258
|
+
### SkillManager
|
|
259
|
+
|
|
260
|
+
The main class for managing and executing skills.
|
|
261
|
+
|
|
262
|
+
#### Constructor
|
|
263
|
+
|
|
264
|
+
```python
|
|
265
|
+
SkillManager(
|
|
266
|
+
skills_dir: Optional[str] = None, # Directory containing skills
|
|
267
|
+
binary_path: Optional[str] = None, # Path to skillbox binary
|
|
268
|
+
cache_dir: Optional[str] = None, # Cache directory for venvs
|
|
269
|
+
allow_network: bool = False # Default network access
|
|
270
|
+
)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
#### Methods
|
|
274
|
+
|
|
275
|
+
- `scan_directory(directory)` - Scan for skills
|
|
276
|
+
- `register_skill(skill_dir)` - Register a single skill
|
|
277
|
+
- `get_skill(name)` - Get skill by name
|
|
278
|
+
- `list_skills()` - List all skills
|
|
279
|
+
- `get_tools_for_claude()` - Get Claude-format tools
|
|
280
|
+
- `get_tools_for_openai()` - Get OpenAI-format tools
|
|
281
|
+
- `execute(skill_name, input_data)` - Execute a skill
|
|
282
|
+
- `handle_tool_calls(response, format)` - Handle LLM tool calls
|
|
283
|
+
- `create_agentic_loop(...)` - Create an agentic loop
|
|
284
|
+
|
|
285
|
+
### ToolFormat
|
|
286
|
+
|
|
287
|
+
Enum for LLM provider formats:
|
|
288
|
+
- `ToolFormat.CLAUDE`
|
|
289
|
+
- `ToolFormat.OPENAI`
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT License
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# SkillLite Python SDK
|
|
2
|
+
|
|
3
|
+
A Python SDK for the SkillLite execution engine, using **OpenAI-compatible API format** as the unified interface.
|
|
4
|
+
|
|
5
|
+
## Supported Providers
|
|
6
|
+
|
|
7
|
+
Works with any OpenAI-compatible LLM provider:
|
|
8
|
+
- **OpenAI** (GPT-4, GPT-3.5, etc.)
|
|
9
|
+
- **Azure OpenAI**
|
|
10
|
+
- **Anthropic Claude** (via OpenAI-compatible endpoint or native)
|
|
11
|
+
- **Google Gemini** (via OpenAI-compatible endpoint)
|
|
12
|
+
- **Local models** (Ollama, vLLM, LMStudio, etc.)
|
|
13
|
+
- **DeepSeek, Qwen, Moonshot, Zhipu**, and other providers
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install skilllite
|
|
19
|
+
|
|
20
|
+
# With OpenAI SDK (recommended, works with all compatible providers)
|
|
21
|
+
pip install skilllite[openai]
|
|
22
|
+
|
|
23
|
+
# With Anthropic SDK (for Claude's native API)
|
|
24
|
+
pip install skilllite[anthropic]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Prerequisites
|
|
28
|
+
|
|
29
|
+
You need to have the `skillbox` binary installed:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# From the skillbox directory
|
|
33
|
+
cargo install --path .
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### Basic Usage (Universal - Works with Any Provider)
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from openai import OpenAI
|
|
42
|
+
from skilllite import SkillManager
|
|
43
|
+
|
|
44
|
+
# Works with ANY OpenAI-compatible provider
|
|
45
|
+
# Just change base_url and api_key for different providers:
|
|
46
|
+
|
|
47
|
+
# OpenAI
|
|
48
|
+
client = OpenAI()
|
|
49
|
+
|
|
50
|
+
# Ollama (local)
|
|
51
|
+
# client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
|
|
52
|
+
|
|
53
|
+
# DeepSeek
|
|
54
|
+
# client = OpenAI(base_url="https://api.deepseek.com/v1", api_key="...")
|
|
55
|
+
|
|
56
|
+
# Qwen (通义千问)
|
|
57
|
+
# client = OpenAI(base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="...")
|
|
58
|
+
|
|
59
|
+
# Moonshot (月之暗面)
|
|
60
|
+
# client = OpenAI(base_url="https://api.moonshot.cn/v1", api_key="...")
|
|
61
|
+
|
|
62
|
+
# Initialize SkillManager
|
|
63
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
64
|
+
|
|
65
|
+
# Get tools (OpenAI-compatible format - works with all providers)
|
|
66
|
+
tools = manager.get_tools()
|
|
67
|
+
|
|
68
|
+
# Call any OpenAI-compatible API
|
|
69
|
+
response = client.chat.completions.create(
|
|
70
|
+
model="gpt-4", # or "llama2", "deepseek-chat", "qwen-turbo", etc.
|
|
71
|
+
tools=tools,
|
|
72
|
+
messages=[{"role": "user", "content": "Please help me with..."}]
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Handle tool calls (same code works for all providers!)
|
|
76
|
+
if response.choices[0].message.tool_calls:
|
|
77
|
+
tool_results = manager.handle_tool_calls(response)
|
|
78
|
+
|
|
79
|
+
# Continue conversation with results
|
|
80
|
+
messages = [
|
|
81
|
+
{"role": "user", "content": "Please help me with..."},
|
|
82
|
+
response.choices[0].message,
|
|
83
|
+
*[r.to_openai_format() for r in tool_results]
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
follow_up = client.chat.completions.create(
|
|
87
|
+
model="gpt-4",
|
|
88
|
+
tools=tools,
|
|
89
|
+
messages=messages
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Agentic Loop (Automatic Multi-turn Tool Execution)
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from openai import OpenAI
|
|
97
|
+
from skilllite import SkillManager
|
|
98
|
+
|
|
99
|
+
# Works with any provider
|
|
100
|
+
client = OpenAI() # or OpenAI(base_url="...", api_key="...")
|
|
101
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
102
|
+
|
|
103
|
+
# Create an agentic loop
|
|
104
|
+
loop = manager.create_agentic_loop(
|
|
105
|
+
client=client,
|
|
106
|
+
model="gpt-4",
|
|
107
|
+
system_prompt="You are a helpful assistant with access to various skills.",
|
|
108
|
+
max_iterations=10,
|
|
109
|
+
temperature=0.7 # Additional kwargs passed to chat.completions.create()
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Run until completion - handles multiple tool calls automatically
|
|
113
|
+
final_response = loop.run("Please analyze this data and generate a report.")
|
|
114
|
+
print(final_response.choices[0].message.content)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Claude Native API (Optional)
|
|
118
|
+
|
|
119
|
+
If you prefer using Claude's native API directly:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import anthropic
|
|
123
|
+
from skilllite import SkillManager
|
|
124
|
+
|
|
125
|
+
client = anthropic.Anthropic()
|
|
126
|
+
manager = SkillManager(skills_dir="./my_skills")
|
|
127
|
+
|
|
128
|
+
# Use Claude-specific methods
|
|
129
|
+
tools = manager.get_tools_for_claude_native()
|
|
130
|
+
response = client.messages.create(
|
|
131
|
+
model="claude-sonnet-4-20250514",
|
|
132
|
+
max_tokens=4096,
|
|
133
|
+
tools=tools,
|
|
134
|
+
messages=[{"role": "user", "content": "..."}]
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if response.stop_reason == "tool_use":
|
|
138
|
+
results = manager.handle_tool_calls_claude_native(response)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Creating Skills
|
|
142
|
+
|
|
143
|
+
Skills are defined in directories with a `SKILL.md` file:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
my_skills/
|
|
147
|
+
├── web-search/
|
|
148
|
+
│ ├── SKILL.md # Metadata and docs (includes dependency declaration)
|
|
149
|
+
│ └── scripts/
|
|
150
|
+
│ └── main.py
|
|
151
|
+
└── calculator/
|
|
152
|
+
├── SKILL.md
|
|
153
|
+
└── scripts/
|
|
154
|
+
└── main.py
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
> **Note**: Python dependencies are declared in the `compatibility` field of `SKILL.md`, not in a separate `requirements.txt` file.
|
|
158
|
+
|
|
159
|
+
### SKILL.md Format
|
|
160
|
+
|
|
161
|
+
```markdown
|
|
162
|
+
---
|
|
163
|
+
name: web-search
|
|
164
|
+
description: Search the web for information
|
|
165
|
+
compatibility: Requires Python 3.x with requests library, network access
|
|
166
|
+
license: MIT
|
|
167
|
+
metadata:
|
|
168
|
+
author: example-org
|
|
169
|
+
version: "1.0"
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
# Web Search Skill
|
|
173
|
+
|
|
174
|
+
This skill searches the web for information.
|
|
175
|
+
|
|
176
|
+
## Input Parameters
|
|
177
|
+
|
|
178
|
+
- `query`: The search query (required)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The `compatibility` field is used to:
|
|
182
|
+
- Detect language (Python/Node/Bash)
|
|
183
|
+
- Enable network access (keywords: network, internet, http, api, web)
|
|
184
|
+
- Auto-install dependencies (known packages like requests, pandas, axios, etc.)
|
|
185
|
+
|
|
186
|
+
### Skill Entry Point
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
# main.py
|
|
190
|
+
import json
|
|
191
|
+
import sys
|
|
192
|
+
|
|
193
|
+
def main():
|
|
194
|
+
# Read input from stdin
|
|
195
|
+
input_data = json.loads(sys.stdin.read())
|
|
196
|
+
|
|
197
|
+
# Process the input
|
|
198
|
+
query = input_data.get("query", "")
|
|
199
|
+
|
|
200
|
+
# Do something...
|
|
201
|
+
result = {"results": [f"Result for: {query}"]}
|
|
202
|
+
|
|
203
|
+
# Output JSON to stdout
|
|
204
|
+
print(json.dumps(result))
|
|
205
|
+
|
|
206
|
+
if __name__ == "__main__":
|
|
207
|
+
main()
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## API Reference
|
|
211
|
+
|
|
212
|
+
### SkillManager
|
|
213
|
+
|
|
214
|
+
The main class for managing and executing skills.
|
|
215
|
+
|
|
216
|
+
#### Constructor
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
SkillManager(
|
|
220
|
+
skills_dir: Optional[str] = None, # Directory containing skills
|
|
221
|
+
binary_path: Optional[str] = None, # Path to skillbox binary
|
|
222
|
+
cache_dir: Optional[str] = None, # Cache directory for venvs
|
|
223
|
+
allow_network: bool = False # Default network access
|
|
224
|
+
)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
#### Methods
|
|
228
|
+
|
|
229
|
+
- `scan_directory(directory)` - Scan for skills
|
|
230
|
+
- `register_skill(skill_dir)` - Register a single skill
|
|
231
|
+
- `get_skill(name)` - Get skill by name
|
|
232
|
+
- `list_skills()` - List all skills
|
|
233
|
+
- `get_tools_for_claude()` - Get Claude-format tools
|
|
234
|
+
- `get_tools_for_openai()` - Get OpenAI-format tools
|
|
235
|
+
- `execute(skill_name, input_data)` - Execute a skill
|
|
236
|
+
- `handle_tool_calls(response, format)` - Handle LLM tool calls
|
|
237
|
+
- `create_agentic_loop(...)` - Create an agentic loop
|
|
238
|
+
|
|
239
|
+
### ToolFormat
|
|
240
|
+
|
|
241
|
+
Enum for LLM provider formats:
|
|
242
|
+
- `ToolFormat.CLAUDE`
|
|
243
|
+
- `ToolFormat.OPENAI`
|
|
244
|
+
|
|
245
|
+
## License
|
|
246
|
+
|
|
247
|
+
MIT License
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "skilllite"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "A lightweight Skills execution engine with LLM integration for LLM agents"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "SkillLite Team", email = "skilllite@example.com"}
|
|
13
|
+
]
|
|
14
|
+
keywords = ["agent", "skills", "llm", "claude", "openai", "sandbox", "tools"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: MacOS",
|
|
20
|
+
"Operating System :: POSIX :: Linux",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.8",
|
|
23
|
+
"Programming Language :: Python :: 3.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
29
|
+
]
|
|
30
|
+
requires-python = ">=3.8"
|
|
31
|
+
dependencies = [
|
|
32
|
+
"pyyaml>=6.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
openai = ["openai>=1.0.0"]
|
|
37
|
+
anthropic = ["anthropic>=0.18.0"]
|
|
38
|
+
mcp = ["mcp>=1.0.0"]
|
|
39
|
+
all = [
|
|
40
|
+
"openai>=1.0.0",
|
|
41
|
+
"anthropic>=0.18.0",
|
|
42
|
+
"mcp>=1.0.0",
|
|
43
|
+
]
|
|
44
|
+
dev = [
|
|
45
|
+
"pytest>=7.0",
|
|
46
|
+
"pytest-asyncio>=0.21.0",
|
|
47
|
+
"black>=23.0",
|
|
48
|
+
"mypy>=1.0",
|
|
49
|
+
"ruff>=0.1.0",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[project.urls]
|
|
53
|
+
Homepage = "https://github.com/EXboys/skilllite"
|
|
54
|
+
Documentation = "https://github.com/EXboys/skilllite#readme"
|
|
55
|
+
Repository = "https://github.com/EXboys/skilllite"
|
|
56
|
+
Issues = "https://github.com/EXboys/skilllite/issues"
|
|
57
|
+
|
|
58
|
+
[project.scripts]
|
|
59
|
+
skilllite = "skilllite.cli:main"
|
|
60
|
+
skilllite-mcp = "skilllite.mcp:main"
|
|
61
|
+
|
|
62
|
+
[tool.setuptools.packages.find]
|
|
63
|
+
where = ["."]
|
|
64
|
+
include = ["skilllite*"]
|
|
65
|
+
|
|
66
|
+
[tool.black]
|
|
67
|
+
line-length = 100
|
|
68
|
+
target-version = ["py38", "py39", "py310", "py311", "py312"]
|
|
69
|
+
|
|
70
|
+
[tool.ruff]
|
|
71
|
+
line-length = 100
|
|
72
|
+
target-version = "py38"
|
|
73
|
+
|
|
74
|
+
[tool.ruff.lint]
|
|
75
|
+
select = ["E", "F", "W", "I", "N", "UP", "B", "C4"]
|
|
76
|
+
ignore = ["E501"]
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
python_version = "3.8"
|
|
80
|
+
warn_return_any = true
|
|
81
|
+
warn_unused_configs = true
|
|
82
|
+
disallow_untyped_defs = true
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
testpaths = ["tests"]
|
|
86
|
+
python_files = ["test_*.py"]
|
|
87
|
+
python_functions = ["test_*"]
|