@rookiestar/eng-lang-tutor 1.0.8 → 1.0.10
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.
Potentially problematic release.
This version of @rookiestar/eng-lang-tutor might be problematic. Click here for more details.
- package/SKILL.md +33 -1
- package/package.json +1 -1
- package/scripts/state_manager.py +1 -26
package/SKILL.md
CHANGED
|
@@ -275,11 +275,43 @@ The bot recognizes these natural language commands:
|
|
|
275
275
|
Step 1: LLM generates keypoint JSON
|
|
276
276
|
Step 2: ⛔ EXECUTE THIS BASH COMMAND (do NOT skip):
|
|
277
277
|
python3 scripts/state_manager.py save_daily --content-type keypoint --content '<ESCAPED_JSON>'
|
|
278
|
+
(This auto-generates audio and saves to audio/YYYY-MM-DD/keypoint_full.mp3)
|
|
278
279
|
Step 3: ⛔ EXECUTE THIS BASH COMMAND (do NOT skip):
|
|
279
280
|
python3 scripts/state_manager.py record_view
|
|
280
|
-
Step 4:
|
|
281
|
+
Step 4: Send audio file via message tool (if audio exists):
|
|
282
|
+
- Read keypoint.json and check if audio.composed field exists
|
|
283
|
+
- If exists, send audio file using message tool with media parameter
|
|
284
|
+
- Audio path: ~/.openclaw/state/eng-lang-tutor/{audio.composed}
|
|
285
|
+
Step 5: Display formatted content to user
|
|
281
286
|
```
|
|
282
287
|
|
|
288
|
+
### Audio File Sending (After Keypoint Save)
|
|
289
|
+
|
|
290
|
+
When keypoint is saved, audio is auto-generated. Send it to user:
|
|
291
|
+
|
|
292
|
+
```
|
|
293
|
+
1. Check keypoint.json for audio field:
|
|
294
|
+
cat ~/.openclaw/state/eng-lang-tutor/daily/YYYY-MM-DD/keypoint.json | grep -o '"audio":{[^}]*}'
|
|
295
|
+
|
|
296
|
+
2. If audio exists, send via message tool:
|
|
297
|
+
{
|
|
298
|
+
"action": "send",
|
|
299
|
+
"media": "~/.openclaw/state/eng-lang-tutor/audio/YYYY-MM-DD/keypoint_full.mp3",
|
|
300
|
+
"caption": "🔊 今日知识点语音版"
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
3. Audio file info is stored in keypoint.json:
|
|
304
|
+
{
|
|
305
|
+
"audio": {
|
|
306
|
+
"composed": "audio/2026-02-23/keypoint_full.mp3",
|
|
307
|
+
"duration_seconds": 37.7,
|
|
308
|
+
"generated_at": "2026-02-23T02:20:14"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**IMPORTANT:** Always send audio file BEFORE displaying text content, so user receives audio first.
|
|
314
|
+
|
|
283
315
|
### After Quiz Generation (MANDATORY)
|
|
284
316
|
```
|
|
285
317
|
Step 1: LLM generates quiz JSON
|
package/package.json
CHANGED
package/scripts/state_manager.py
CHANGED
|
@@ -324,19 +324,7 @@ class StateManager:
|
|
|
324
324
|
'duration_seconds': audio_result.get('duration_seconds'),
|
|
325
325
|
'generated_at': datetime.now().isoformat()
|
|
326
326
|
}
|
|
327
|
-
#
|
|
328
|
-
audio_tag = f"[AUDIO:{audio_path}]"
|
|
329
|
-
if 'display' in content:
|
|
330
|
-
if isinstance(content['display'], dict):
|
|
331
|
-
# Add audio tag to footer if display is an object
|
|
332
|
-
footer = content['display'].get('footer', '')
|
|
333
|
-
if audio_tag not in footer:
|
|
334
|
-
content['display']['footer'] = f"{audio_tag}\n{footer}" if footer else audio_tag
|
|
335
|
-
elif isinstance(content['display'], str):
|
|
336
|
-
# Append to display if it's a string
|
|
337
|
-
if audio_tag not in content['display']:
|
|
338
|
-
content['display'] = f"{audio_tag}\n\n{content['display']}"
|
|
339
|
-
# Re-save with audio info and display update
|
|
327
|
+
# Re-save with audio info
|
|
340
328
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
341
329
|
json.dump(content, f, ensure_ascii=False, indent=2)
|
|
342
330
|
except Exception as e:
|
|
@@ -407,19 +395,6 @@ class StateManager:
|
|
|
407
395
|
'generated_at': datetime.now().isoformat()
|
|
408
396
|
}
|
|
409
397
|
|
|
410
|
-
# Inject [AUDIO:...] tag for Gateway to send voice message
|
|
411
|
-
audio_tag = f"[AUDIO:{audio_path}]"
|
|
412
|
-
if 'display' in keypoint:
|
|
413
|
-
if isinstance(keypoint['display'], dict):
|
|
414
|
-
# Add audio tag to footer if display is an object
|
|
415
|
-
footer = keypoint['display'].get('footer', '')
|
|
416
|
-
if audio_tag not in footer:
|
|
417
|
-
keypoint['display']['footer'] = f"{audio_tag}\n{footer}" if footer else audio_tag
|
|
418
|
-
elif isinstance(keypoint['display'], str):
|
|
419
|
-
# Append to display if it's a string
|
|
420
|
-
if audio_tag not in keypoint['display']:
|
|
421
|
-
keypoint['display'] = f"{audio_tag}\n\n{keypoint['display']}"
|
|
422
|
-
|
|
423
398
|
# Save updated keypoint
|
|
424
399
|
daily_path = self.get_daily_dir(target_date)
|
|
425
400
|
file_path = daily_path / "keypoint.json"
|