Add speak-summary skill: turn any text or summary into a listenable MP3 - #2797
Merged
Merged
Conversation
Adds a skill that converts text, markdown, or the output of another skill into an MP3 using Kyutai pocket-tts, a small neural TTS model that runs on CPU. No existing skill in the collection generates audio, so this fills a gap rather than duplicating one. It is designed as a terminal step in a chain: roundup, daily-prep, or meeting-minutes produce the text, speak-summary makes it listenable. Two details worth calling out: - The bulk of SKILL.md is guidance on rewriting written prose for the ear before synthesising. Feeding markdown straight into a TTS engine produces something technically correct and unlistenable, so that step carries most of the value. - Synthesis is local and CPU-only, so nothing is sent to a cloud speech service and the skill works unattended in a headless container as well as on a laptop. The bundled script bootstraps pocket-tts into a cached virtualenv on first use, selecting a Python in the supported >=3.10,<3.15 range rather than assuming python3 qualifies, and failing with actionable guidance when none is available. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1a70aa08-b622-4825-ad63-5a12370add1f
Contributor
🔒 PR Risk Scan ResultsScanned 2 changed file(s).
|
Contributor
🔍 Vally Lint Results✅ All checks passed
Summary
Full linter output |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a terminal skill that converts written summaries into locally generated audio.
Changes:
- Adds guidance for rewriting text for listening.
- Adds local
pocket-ttssynthesis, chunking, and encoding. - Registers the skill in generated documentation.
Show a summary per file
| File | Description |
|---|---|
skills/speak-summary/SKILL.md |
Defines usage, preparation, voices, and output guidance. |
skills/speak-summary/scripts/tts.sh |
Bootstraps TTS and generates MP3/M4A audio. |
docs/README.skills.md |
Adds the skill to the catalog. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 3/3 changed files
- Comments generated: 2
- Review effort level: Balanced
| [ -n "$VOICE" ] && ARGS+=(--voice "$VOICE") | ||
| N=$((N+1)) | ||
| echo " synthesising chunk $N ..." >&2 | ||
| "$TTS" "${ARGS[@]}" >/dev/null |
|
|
||
| # pocket-tts quality degrades on very long inputs, so split into ~600-char chunks | ||
| # on sentence boundaries, synthesise each, then concatenate. | ||
| python3 - "$IN" "$WORK" <<'PY' |
aaronpowell
approved these changes
Aug 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
A
speak-summaryskill that converts text, markdown, or the output of another skill into an MP3 using local, CPU-only neural text-to-speech.Why
There is no audio generation skill in the collection today. I checked before building:
resemble-detectdoes deepfake audio detection (the opposite direction), and the media skills (generate-image,screen-recording,image-manipulation-image-magick) are image and GIF only —screen-recordingexplicitly notes "No audio support in GIF". So this fills a gap rather than duplicating existing coverage.The use case is asynchronous catch-up: generate a digest, listen to it while commuting, cooking, or away from a screen.
Designed to chain
This is deliberately a terminal step, not a self-contained tool. It does not gather or summarise anything — that would duplicate
roundup, which already does multi-source date-ranged briefings well. The intended pattern is:roundup→speak-summary— spoken status briefingdaily-prep→speak-summary— tomorrow's schedule, listened to tonightmeeting-minutes→speak-summary— catch up on a meeting you missedThe upstream skill owns what to say; this one owns how it sounds. Pairing it with a scheduled workflow gives you a digest waiting before breakfast.
The part that carries the value
Most of
SKILL.mdis guidance on rewriting written prose for the ear before synthesising. Piping markdown straight into a TTS engine gives you something technically correct and genuinely unpleasant to listen to — read-aloud URLs, bullet fragments with no connective tissue,2026-08-20spoken as digits.So the skill instructs the model to expand abbreviations on first use, speak dates naturally, replace bullets with connective prose, signpost transitions, drop visual-only content like tables and code blocks, and close with the actions since a listener cannot scroll back.
Privacy and portability
Synthesis uses Kyutai
pocket-tts, a small neural model built to run on CPUs. This was a deliberate choice over a cloud TTS API:It is roughly 6x faster than real-time; a 5-minute briefing renders in about 50 seconds.
Implementation notes
scripts/tts.shbootstrapspocket-ttsinto a cached virtualenv on first use, so there is no manual setup step.Two things it handles that are easy to get wrong:
pocket-ttsrequires>=3.10,<3.15. The script searches for a compatible interpreter rather than assumingpython3qualifies, and fails with actionable guidance when none exists. I hit this genuinely while testing on Python 3.15, where the naive approach fails confusingly mid-run.ffmpegis preferred for encoding, with a fallback to macOSafconvert(emitting.m4a) when it is absent.Testing
npm run skill:validate— passes (412 skills valid)npm run build— regenerateddocs/README.skills.mdpocket-ttsabsent fromPATH: creates the venv, installs, and synthesises successfullyNote on voice cloning
pocket-ttssupports voice cloning, so the skill documents it — along with explicit guidance not to clone a real person's voice without their consent.