skill-optimizer 0.3.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.
- skill_optimizer-0.3.0/LICENSE +21 -0
- skill_optimizer-0.3.0/PKG-INFO +311 -0
- skill_optimizer-0.3.0/README.md +285 -0
- skill_optimizer-0.3.0/pyproject.toml +44 -0
- skill_optimizer-0.3.0/setup.cfg +4 -0
- skill_optimizer-0.3.0/src/skill_optimizer/__init__.py +50 -0
- skill_optimizer-0.3.0/src/skill_optimizer/optimizer.py +478 -0
- skill_optimizer-0.3.0/src/skill_optimizer/session.py +334 -0
- skill_optimizer-0.3.0/src/skill_optimizer/suggestions.py +223 -0
- skill_optimizer-0.3.0/src/skill_optimizer.egg-info/PKG-INFO +311 -0
- skill_optimizer-0.3.0/src/skill_optimizer.egg-info/SOURCES.txt +13 -0
- skill_optimizer-0.3.0/src/skill_optimizer.egg-info/dependency_links.txt +1 -0
- skill_optimizer-0.3.0/src/skill_optimizer.egg-info/requires.txt +6 -0
- skill_optimizer-0.3.0/src/skill_optimizer.egg-info/top_level.txt +1 -0
- skill_optimizer-0.3.0/test/test_all.py +421 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MEET PATEL
|
|
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.
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skill-optimizer
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Auto-track and optimize Claude skills using AI-powered conversation analysis
|
|
5
|
+
Author-email: Meet Patel <meet84046@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Repository, https://github.com/meet-rocking/skill-optimizer
|
|
8
|
+
Keywords: claude,anthropic,skills,optimization,ai
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: pyyaml>=6.0
|
|
21
|
+
Requires-Dist: anthropic>=0.50.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# Skill Optimizer
|
|
28
|
+
|
|
29
|
+
AI-powered skill optimization using Claude to analyze conversations and automatically improve SKILL.md files.
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install skill-optimizer
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from skill_optimizer import SkillOptimizer
|
|
41
|
+
|
|
42
|
+
# Initialize with your API key
|
|
43
|
+
optimizer = SkillOptimizer(
|
|
44
|
+
skills_dir=".claude/skills",
|
|
45
|
+
api_key="sk-ant-api03-..."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Start a session (with optional user/org tracking)
|
|
49
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
50
|
+
|
|
51
|
+
# Track the conversation
|
|
52
|
+
session.add_message("user", "Create a sales dashboard")
|
|
53
|
+
session.track_skill("dashboard", exec_time_ms=2000, success=True)
|
|
54
|
+
session.add_message("assistant", "Here's your dashboard with pie charts...")
|
|
55
|
+
session.add_message("user", "Actually, can you use bar charts instead?")
|
|
56
|
+
session.add_message("assistant", "Updated to bar charts!")
|
|
57
|
+
|
|
58
|
+
# End session - Claude AI analyzes the conversation
|
|
59
|
+
session.end_sync() # or: await session.end()
|
|
60
|
+
|
|
61
|
+
# View pending suggestions
|
|
62
|
+
print(optimizer.get_suggestions_summary())
|
|
63
|
+
|
|
64
|
+
# Apply suggestions to SKILL.md files
|
|
65
|
+
changes = optimizer.apply()
|
|
66
|
+
print(f"Updated: {list(changes.keys())}")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## How It Works
|
|
70
|
+
|
|
71
|
+
### Flow Diagram
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
75
|
+
│ SESSION │
|
|
76
|
+
│ │
|
|
77
|
+
│ 1. start_session() │
|
|
78
|
+
│ │ │
|
|
79
|
+
│ ▼ │
|
|
80
|
+
│ 2. During conversation: │
|
|
81
|
+
│ session.add_message("user", "...") │
|
|
82
|
+
│ session.track_skill("docx", exec_time_ms=1500) │
|
|
83
|
+
│ session.add_message("assistant", "...") │
|
|
84
|
+
│ │ │
|
|
85
|
+
│ ▼ │
|
|
86
|
+
│ 3. session.end() │
|
|
87
|
+
│ │ │
|
|
88
|
+
│ ▼ │
|
|
89
|
+
│ ┌─────────────────────────────────────┐ │
|
|
90
|
+
│ │ Claude AI analyzes conversation: │ │
|
|
91
|
+
│ │ - Finds corrections │ │
|
|
92
|
+
│ │ - Extracts preferences │ │
|
|
93
|
+
│ │ - Identifies new triggers │ │
|
|
94
|
+
│ │ - Suggests improvements │ │
|
|
95
|
+
│ └─────────────────────────────────────┘ │
|
|
96
|
+
│ │ │
|
|
97
|
+
│ ▼ │
|
|
98
|
+
│ suggestions.json (pending suggestions) │
|
|
99
|
+
│ │
|
|
100
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
101
|
+
│
|
|
102
|
+
▼
|
|
103
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
104
|
+
│ APPLY (when ready) │
|
|
105
|
+
│ │
|
|
106
|
+
│ optimizer.apply() │
|
|
107
|
+
│ │ │
|
|
108
|
+
│ ▼ │
|
|
109
|
+
│ Updates SKILL.md files with: │
|
|
110
|
+
│ - New trigger phrases in description │
|
|
111
|
+
│ - User Preferences section │
|
|
112
|
+
│ - Learned Corrections section │
|
|
113
|
+
│ - Updated Metrics │
|
|
114
|
+
│ │ │
|
|
115
|
+
│ ▼ │
|
|
116
|
+
│ Marks suggestions as applied (kept in JSON as history) │
|
|
117
|
+
│ Use optimizer.store.clear_applied() to clean up │
|
|
118
|
+
│ │
|
|
119
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## File Structure
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
.claude/skills/
|
|
126
|
+
├── dashboard/
|
|
127
|
+
│ └── SKILL.md ← Updated by optimizer
|
|
128
|
+
├── docx/
|
|
129
|
+
│ └── SKILL.md
|
|
130
|
+
│
|
|
131
|
+
└── .optimizer/ ← Created automatically
|
|
132
|
+
├── suggestions.json ← Pending suggestions
|
|
133
|
+
└── metrics.json ← Usage metrics
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## API Reference
|
|
137
|
+
|
|
138
|
+
### SkillOptimizer
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
optimizer = SkillOptimizer(
|
|
142
|
+
skills_dir=".claude/skills", # Path to skills
|
|
143
|
+
api_key="sk-ant-...", # Anthropic API key
|
|
144
|
+
data_dir=None, # Optional: custom data directory
|
|
145
|
+
model="claude-sonnet-4-20250514" # Model for analysis
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Session management
|
|
149
|
+
session = optimizer.start_session()
|
|
150
|
+
session = optimizer.start_session(session_id="custom-id")
|
|
151
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
152
|
+
|
|
153
|
+
# View suggestions
|
|
154
|
+
suggestions = optimizer.get_suggestions() # All pending
|
|
155
|
+
suggestions = optimizer.get_suggestions("dashboard") # For one skill
|
|
156
|
+
suggestions = optimizer.get_suggestions(user_id="user_123") # For one user
|
|
157
|
+
suggestions = optimizer.get_suggestions(org="acme-corp") # For one org
|
|
158
|
+
print(optimizer.get_suggestions_summary()) # Text summary
|
|
159
|
+
|
|
160
|
+
# Apply suggestions (marks them as applied, writes to SKILL.md)
|
|
161
|
+
changes = optimizer.apply() # Apply all
|
|
162
|
+
changes = optimizer.apply("dashboard") # Apply one skill
|
|
163
|
+
changes = optimizer.apply(dry_run=True) # Preview only
|
|
164
|
+
|
|
165
|
+
# Applied suggestions stay in suggestions.json as history.
|
|
166
|
+
# They won't appear in get_suggestions() anymore.
|
|
167
|
+
# To permanently remove applied suggestions from the file:
|
|
168
|
+
optimizer.store.clear_applied()
|
|
169
|
+
|
|
170
|
+
# Metrics
|
|
171
|
+
metrics = optimizer.get_metrics("dashboard")
|
|
172
|
+
all_metrics = optimizer.get_all_metrics()
|
|
173
|
+
|
|
174
|
+
# Status
|
|
175
|
+
print(optimizer.status())
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Session
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
182
|
+
|
|
183
|
+
# Track conversation
|
|
184
|
+
session.add_message("user", "Create a document")
|
|
185
|
+
session.add_message("assistant", "Here's your document...")
|
|
186
|
+
|
|
187
|
+
# Track skill usage
|
|
188
|
+
session.track_skill(
|
|
189
|
+
skill_name="docx",
|
|
190
|
+
exec_time_ms=1500,
|
|
191
|
+
success=True,
|
|
192
|
+
error=None # Optional error message if failed
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
# End and analyze (choose one)
|
|
196
|
+
await session.end() # Async
|
|
197
|
+
session.end_sync() # Sync
|
|
198
|
+
|
|
199
|
+
# Properties
|
|
200
|
+
session.session_id # Unique ID
|
|
201
|
+
session.user_id # User identifier (optional)
|
|
202
|
+
session.org # Organization identifier (optional)
|
|
203
|
+
session.messages # List of messages
|
|
204
|
+
session.skill_usages # List of skill usages
|
|
205
|
+
session.duration_seconds # Session duration
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Suggestion
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
@dataclass
|
|
212
|
+
class Suggestion:
|
|
213
|
+
skill_name: str # Which skill this is for
|
|
214
|
+
category: str # "correction", "preference", "trigger", "improvement"
|
|
215
|
+
content: str # The actual suggestion
|
|
216
|
+
reason: str # Why (from conversation analysis)
|
|
217
|
+
session_id: str # Which session it came from
|
|
218
|
+
user_id: str # Which user created this session
|
|
219
|
+
org: str # Which organization the user belongs to
|
|
220
|
+
created_at: str # Timestamp
|
|
221
|
+
applied: bool # Whether it's been applied
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Integration Example
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
from skill_optimizer import SkillOptimizer
|
|
228
|
+
|
|
229
|
+
optimizer = SkillOptimizer(".claude/skills", api_key="...")
|
|
230
|
+
|
|
231
|
+
async def handle_conversation(messages: list, skills_used: list):
|
|
232
|
+
"""Handle a complete conversation."""
|
|
233
|
+
|
|
234
|
+
# Start session with user/org tracking
|
|
235
|
+
session = optimizer.start_session(user_id="user_42", org="acme-corp")
|
|
236
|
+
|
|
237
|
+
# Add all messages
|
|
238
|
+
for msg in messages:
|
|
239
|
+
session.add_message(msg["role"], msg["content"])
|
|
240
|
+
|
|
241
|
+
# Add skill usage
|
|
242
|
+
for skill in skills_used:
|
|
243
|
+
session.track_skill(
|
|
244
|
+
skill_name=skill["name"],
|
|
245
|
+
exec_time_ms=skill["time_ms"],
|
|
246
|
+
success=skill["success"]
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# Analyze with AI
|
|
250
|
+
suggestions = await session.end()
|
|
251
|
+
|
|
252
|
+
print(f"Found {len(suggestions)} suggestions")
|
|
253
|
+
return suggestions
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
# Later: apply all pending suggestions
|
|
257
|
+
def daily_optimization():
|
|
258
|
+
changes = optimizer.apply()
|
|
259
|
+
for skill, change in changes.items():
|
|
260
|
+
print(f"Updated {skill}: {change}")
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## What Claude Analyzes
|
|
264
|
+
|
|
265
|
+
When `session.end()` is called, Claude looks for:
|
|
266
|
+
|
|
267
|
+
| Category | Examples |
|
|
268
|
+
|----------|----------|
|
|
269
|
+
| **Corrections** | "Actually, I wanted...", "That's not right...", "Can you change..." |
|
|
270
|
+
| **Preferences** | "I prefer...", "Always use...", "Next time..." |
|
|
271
|
+
| **Triggers** | "When I say X, I mean...", alternative phrasings |
|
|
272
|
+
| **Improvements** | Performance issues, missing features, better defaults |
|
|
273
|
+
|
|
274
|
+
## Example Updated SKILL.md
|
|
275
|
+
|
|
276
|
+
After `optimizer.apply()`:
|
|
277
|
+
|
|
278
|
+
```markdown
|
|
279
|
+
---
|
|
280
|
+
name: dashboard
|
|
281
|
+
description: "Create dashboards. Triggers: 'analytics', 'charts', 'visualization'"
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
# Dashboard Skill
|
|
285
|
+
|
|
286
|
+
Creates interactive dashboards.
|
|
287
|
+
|
|
288
|
+
## User Preferences
|
|
289
|
+
|
|
290
|
+
- Use bar charts instead of pie charts for comparisons
|
|
291
|
+
- Dark theme by default
|
|
292
|
+
- Include date range selector
|
|
293
|
+
|
|
294
|
+
## Learned Corrections
|
|
295
|
+
|
|
296
|
+
- Always include a title on charts
|
|
297
|
+
- Export button should be visible
|
|
298
|
+
|
|
299
|
+
## Metrics
|
|
300
|
+
|
|
301
|
+
| Metric | Value |
|
|
302
|
+
|--------|-------|
|
|
303
|
+
| Total Calls | 47 |
|
|
304
|
+
| Success Rate | 91.5% |
|
|
305
|
+
| Avg Exec Time | 1850ms |
|
|
306
|
+
| Last Used | 2025-02-05T10:30:00 |
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
MIT
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Skill Optimizer
|
|
2
|
+
|
|
3
|
+
AI-powered skill optimization using Claude to analyze conversations and automatically improve SKILL.md files.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install skill-optimizer
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from skill_optimizer import SkillOptimizer
|
|
15
|
+
|
|
16
|
+
# Initialize with your API key
|
|
17
|
+
optimizer = SkillOptimizer(
|
|
18
|
+
skills_dir=".claude/skills",
|
|
19
|
+
api_key="sk-ant-api03-..."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# Start a session (with optional user/org tracking)
|
|
23
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
24
|
+
|
|
25
|
+
# Track the conversation
|
|
26
|
+
session.add_message("user", "Create a sales dashboard")
|
|
27
|
+
session.track_skill("dashboard", exec_time_ms=2000, success=True)
|
|
28
|
+
session.add_message("assistant", "Here's your dashboard with pie charts...")
|
|
29
|
+
session.add_message("user", "Actually, can you use bar charts instead?")
|
|
30
|
+
session.add_message("assistant", "Updated to bar charts!")
|
|
31
|
+
|
|
32
|
+
# End session - Claude AI analyzes the conversation
|
|
33
|
+
session.end_sync() # or: await session.end()
|
|
34
|
+
|
|
35
|
+
# View pending suggestions
|
|
36
|
+
print(optimizer.get_suggestions_summary())
|
|
37
|
+
|
|
38
|
+
# Apply suggestions to SKILL.md files
|
|
39
|
+
changes = optimizer.apply()
|
|
40
|
+
print(f"Updated: {list(changes.keys())}")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## How It Works
|
|
44
|
+
|
|
45
|
+
### Flow Diagram
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
49
|
+
│ SESSION │
|
|
50
|
+
│ │
|
|
51
|
+
│ 1. start_session() │
|
|
52
|
+
│ │ │
|
|
53
|
+
│ ▼ │
|
|
54
|
+
│ 2. During conversation: │
|
|
55
|
+
│ session.add_message("user", "...") │
|
|
56
|
+
│ session.track_skill("docx", exec_time_ms=1500) │
|
|
57
|
+
│ session.add_message("assistant", "...") │
|
|
58
|
+
│ │ │
|
|
59
|
+
│ ▼ │
|
|
60
|
+
│ 3. session.end() │
|
|
61
|
+
│ │ │
|
|
62
|
+
│ ▼ │
|
|
63
|
+
│ ┌─────────────────────────────────────┐ │
|
|
64
|
+
│ │ Claude AI analyzes conversation: │ │
|
|
65
|
+
│ │ - Finds corrections │ │
|
|
66
|
+
│ │ - Extracts preferences │ │
|
|
67
|
+
│ │ - Identifies new triggers │ │
|
|
68
|
+
│ │ - Suggests improvements │ │
|
|
69
|
+
│ └─────────────────────────────────────┘ │
|
|
70
|
+
│ │ │
|
|
71
|
+
│ ▼ │
|
|
72
|
+
│ suggestions.json (pending suggestions) │
|
|
73
|
+
│ │
|
|
74
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
75
|
+
│
|
|
76
|
+
▼
|
|
77
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
78
|
+
│ APPLY (when ready) │
|
|
79
|
+
│ │
|
|
80
|
+
│ optimizer.apply() │
|
|
81
|
+
│ │ │
|
|
82
|
+
│ ▼ │
|
|
83
|
+
│ Updates SKILL.md files with: │
|
|
84
|
+
│ - New trigger phrases in description │
|
|
85
|
+
│ - User Preferences section │
|
|
86
|
+
│ - Learned Corrections section │
|
|
87
|
+
│ - Updated Metrics │
|
|
88
|
+
│ │ │
|
|
89
|
+
│ ▼ │
|
|
90
|
+
│ Marks suggestions as applied (kept in JSON as history) │
|
|
91
|
+
│ Use optimizer.store.clear_applied() to clean up │
|
|
92
|
+
│ │
|
|
93
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## File Structure
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
.claude/skills/
|
|
100
|
+
├── dashboard/
|
|
101
|
+
│ └── SKILL.md ← Updated by optimizer
|
|
102
|
+
├── docx/
|
|
103
|
+
│ └── SKILL.md
|
|
104
|
+
│
|
|
105
|
+
└── .optimizer/ ← Created automatically
|
|
106
|
+
├── suggestions.json ← Pending suggestions
|
|
107
|
+
└── metrics.json ← Usage metrics
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## API Reference
|
|
111
|
+
|
|
112
|
+
### SkillOptimizer
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
optimizer = SkillOptimizer(
|
|
116
|
+
skills_dir=".claude/skills", # Path to skills
|
|
117
|
+
api_key="sk-ant-...", # Anthropic API key
|
|
118
|
+
data_dir=None, # Optional: custom data directory
|
|
119
|
+
model="claude-sonnet-4-20250514" # Model for analysis
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Session management
|
|
123
|
+
session = optimizer.start_session()
|
|
124
|
+
session = optimizer.start_session(session_id="custom-id")
|
|
125
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
126
|
+
|
|
127
|
+
# View suggestions
|
|
128
|
+
suggestions = optimizer.get_suggestions() # All pending
|
|
129
|
+
suggestions = optimizer.get_suggestions("dashboard") # For one skill
|
|
130
|
+
suggestions = optimizer.get_suggestions(user_id="user_123") # For one user
|
|
131
|
+
suggestions = optimizer.get_suggestions(org="acme-corp") # For one org
|
|
132
|
+
print(optimizer.get_suggestions_summary()) # Text summary
|
|
133
|
+
|
|
134
|
+
# Apply suggestions (marks them as applied, writes to SKILL.md)
|
|
135
|
+
changes = optimizer.apply() # Apply all
|
|
136
|
+
changes = optimizer.apply("dashboard") # Apply one skill
|
|
137
|
+
changes = optimizer.apply(dry_run=True) # Preview only
|
|
138
|
+
|
|
139
|
+
# Applied suggestions stay in suggestions.json as history.
|
|
140
|
+
# They won't appear in get_suggestions() anymore.
|
|
141
|
+
# To permanently remove applied suggestions from the file:
|
|
142
|
+
optimizer.store.clear_applied()
|
|
143
|
+
|
|
144
|
+
# Metrics
|
|
145
|
+
metrics = optimizer.get_metrics("dashboard")
|
|
146
|
+
all_metrics = optimizer.get_all_metrics()
|
|
147
|
+
|
|
148
|
+
# Status
|
|
149
|
+
print(optimizer.status())
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Session
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
session = optimizer.start_session(user_id="user_123", org="acme-corp")
|
|
156
|
+
|
|
157
|
+
# Track conversation
|
|
158
|
+
session.add_message("user", "Create a document")
|
|
159
|
+
session.add_message("assistant", "Here's your document...")
|
|
160
|
+
|
|
161
|
+
# Track skill usage
|
|
162
|
+
session.track_skill(
|
|
163
|
+
skill_name="docx",
|
|
164
|
+
exec_time_ms=1500,
|
|
165
|
+
success=True,
|
|
166
|
+
error=None # Optional error message if failed
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# End and analyze (choose one)
|
|
170
|
+
await session.end() # Async
|
|
171
|
+
session.end_sync() # Sync
|
|
172
|
+
|
|
173
|
+
# Properties
|
|
174
|
+
session.session_id # Unique ID
|
|
175
|
+
session.user_id # User identifier (optional)
|
|
176
|
+
session.org # Organization identifier (optional)
|
|
177
|
+
session.messages # List of messages
|
|
178
|
+
session.skill_usages # List of skill usages
|
|
179
|
+
session.duration_seconds # Session duration
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Suggestion
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
@dataclass
|
|
186
|
+
class Suggestion:
|
|
187
|
+
skill_name: str # Which skill this is for
|
|
188
|
+
category: str # "correction", "preference", "trigger", "improvement"
|
|
189
|
+
content: str # The actual suggestion
|
|
190
|
+
reason: str # Why (from conversation analysis)
|
|
191
|
+
session_id: str # Which session it came from
|
|
192
|
+
user_id: str # Which user created this session
|
|
193
|
+
org: str # Which organization the user belongs to
|
|
194
|
+
created_at: str # Timestamp
|
|
195
|
+
applied: bool # Whether it's been applied
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Integration Example
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
from skill_optimizer import SkillOptimizer
|
|
202
|
+
|
|
203
|
+
optimizer = SkillOptimizer(".claude/skills", api_key="...")
|
|
204
|
+
|
|
205
|
+
async def handle_conversation(messages: list, skills_used: list):
|
|
206
|
+
"""Handle a complete conversation."""
|
|
207
|
+
|
|
208
|
+
# Start session with user/org tracking
|
|
209
|
+
session = optimizer.start_session(user_id="user_42", org="acme-corp")
|
|
210
|
+
|
|
211
|
+
# Add all messages
|
|
212
|
+
for msg in messages:
|
|
213
|
+
session.add_message(msg["role"], msg["content"])
|
|
214
|
+
|
|
215
|
+
# Add skill usage
|
|
216
|
+
for skill in skills_used:
|
|
217
|
+
session.track_skill(
|
|
218
|
+
skill_name=skill["name"],
|
|
219
|
+
exec_time_ms=skill["time_ms"],
|
|
220
|
+
success=skill["success"]
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# Analyze with AI
|
|
224
|
+
suggestions = await session.end()
|
|
225
|
+
|
|
226
|
+
print(f"Found {len(suggestions)} suggestions")
|
|
227
|
+
return suggestions
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
# Later: apply all pending suggestions
|
|
231
|
+
def daily_optimization():
|
|
232
|
+
changes = optimizer.apply()
|
|
233
|
+
for skill, change in changes.items():
|
|
234
|
+
print(f"Updated {skill}: {change}")
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## What Claude Analyzes
|
|
238
|
+
|
|
239
|
+
When `session.end()` is called, Claude looks for:
|
|
240
|
+
|
|
241
|
+
| Category | Examples |
|
|
242
|
+
|----------|----------|
|
|
243
|
+
| **Corrections** | "Actually, I wanted...", "That's not right...", "Can you change..." |
|
|
244
|
+
| **Preferences** | "I prefer...", "Always use...", "Next time..." |
|
|
245
|
+
| **Triggers** | "When I say X, I mean...", alternative phrasings |
|
|
246
|
+
| **Improvements** | Performance issues, missing features, better defaults |
|
|
247
|
+
|
|
248
|
+
## Example Updated SKILL.md
|
|
249
|
+
|
|
250
|
+
After `optimizer.apply()`:
|
|
251
|
+
|
|
252
|
+
```markdown
|
|
253
|
+
---
|
|
254
|
+
name: dashboard
|
|
255
|
+
description: "Create dashboards. Triggers: 'analytics', 'charts', 'visualization'"
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
# Dashboard Skill
|
|
259
|
+
|
|
260
|
+
Creates interactive dashboards.
|
|
261
|
+
|
|
262
|
+
## User Preferences
|
|
263
|
+
|
|
264
|
+
- Use bar charts instead of pie charts for comparisons
|
|
265
|
+
- Dark theme by default
|
|
266
|
+
- Include date range selector
|
|
267
|
+
|
|
268
|
+
## Learned Corrections
|
|
269
|
+
|
|
270
|
+
- Always include a title on charts
|
|
271
|
+
- Export button should be visible
|
|
272
|
+
|
|
273
|
+
## Metrics
|
|
274
|
+
|
|
275
|
+
| Metric | Value |
|
|
276
|
+
|--------|-------|
|
|
277
|
+
| Total Calls | 47 |
|
|
278
|
+
| Success Rate | 91.5% |
|
|
279
|
+
| Avg Exec Time | 1850ms |
|
|
280
|
+
| Last Used | 2025-02-05T10:30:00 |
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## License
|
|
284
|
+
|
|
285
|
+
MIT
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "skill-optimizer"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Auto-track and optimize Claude skills using AI-powered conversation analysis"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Meet Patel", email = "meet84046@gmail.com"}
|
|
13
|
+
]
|
|
14
|
+
keywords = ["claude", "anthropic", "skills", "optimization", "ai"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 4 - Beta",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
requires-python = ">=3.9"
|
|
26
|
+
dependencies = [
|
|
27
|
+
"pyyaml>=6.0",
|
|
28
|
+
"anthropic>=0.50.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.optional-dependencies]
|
|
32
|
+
dev = [
|
|
33
|
+
"pytest>=7.0.0",
|
|
34
|
+
"pytest-asyncio>=0.21.0",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Repository = "https://github.com/meet-rocking/skill-optimizer"
|
|
39
|
+
|
|
40
|
+
[tool.setuptools.packages.find]
|
|
41
|
+
where = ["src"]
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.package-data]
|
|
44
|
+
"*" = ["*.yaml", "*.json"]
|