Skip to content

Add speak-summary skill: turn any text or summary into a listenable MP3 - #2797

Merged
aaronpowell merged 1 commit into
github:mainfrom
Sam-Rowe:add-speak-summary-skill
Aug 27, 2026
Merged

aaronpowell merged 1 commit into
github:mainfrom
Sam-Rowe:add-speak-summary-skill

Conversation

@Sam-Rowe

Copy link
Copy Markdown
Contributor

What this adds

A speak-summary skill 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-detect does deepfake audio detection (the opposite direction), and the media skills (generate-image, screen-recording, image-manipulation-image-magick) are image and GIF only — screen-recording explicitly 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:

  • roundupspeak-summary — spoken status briefing
  • daily-prepspeak-summary — tomorrow's schedule, listened to tonight
  • meeting-minutesspeak-summary — catch up on a meeting you missed

The 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.md is 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-20 spoken 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:

  • Nothing leaves the machine, which matters when the summarised content is confidential.
  • No API key, so there is no paid-service dependency.
  • CPU-only, so it runs unattended in a headless cloud agent or CI container just as well as on a laptop.

It is roughly 6x faster than real-time; a 5-minute briefing renders in about 50 seconds.

Implementation notes

scripts/tts.sh bootstraps pocket-tts into a cached virtualenv on first use, so there is no manual setup step.

Two things it handles that are easy to get wrong:

  • Python version. pocket-tts requires >=3.10,<3.15. The script searches for a compatible interpreter rather than assuming python3 qualifies, 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.
  • Chunking. Quality degrades on long inputs, so text is split on sentence boundaries into ~600 character chunks (falling back to comma boundaries for very long sentences), synthesised individually, and concatenated. Output is mono 96kbps MP3 — small enough to sync to a phone, fine for speech.

ffmpeg is preferred for encoding, with a fallback to macOS afconvert (emitting .m4a) when it is absent.

Testing

  • npm run skill:validate — passes (412 skills valid)
  • npm run build — regenerated docs/README.skills.md
  • Synthesised multi-chunk briefings end to end and verified durations against word counts (~180 wpm) to confirm no text is silently dropped
  • Verified the clean-slate bootstrap with pocket-tts absent from PATH: creates the venv, installs, and synthesises successfully
  • Verified the failure path on an unsupported Python produces a clear message rather than a crash

Note on voice cloning

pocket-tts supports voice cloning, so the skill documents it — along with explicit guidance not to clone a real person's voice without their consent.

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
Copilot AI balanced review requested due to automatic review settings August 25, 2026 09:32
@Sam-Rowe
Sam-Rowe requested a review from aaronpowell as a code owner August 25, 2026 09:32
@github-actions github-actions Bot added new-submission PR adds at least one new contribution skills PR touches skills labels Aug 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔒 PR Risk Scan Results

Scanned 2 changed file(s).

Severity Count
🔴 High 0
🟠 Medium 0
ℹ️ Info 1
Severity Rule File Line Match
ℹ️ skill-script-touched skills/speak-summary/scripts/tts.sh 1 skills/speak-summary/scripts/tts.sh

This is an automated soft-gate report. Findings indicate review targets and do not block merge by themselves.

@github-actions

Copy link
Copy Markdown
Contributor

🔍 Vally Lint Results

✅ All checks passed

Scope Checked
Skills 1
Agents 0
Total 1
Severity Count
❌ Errors 0
⚠️ Warnings 0
ℹ️ Advisories 0

Summary

Level Finding
ℹ️ ✅ speak-summary (2/2 checks passed)
ℹ️ ✓ [spec-compliance] All 1 skill(s) are spec-compliant.
ℹ️ ✓ spec-compliance: All spec checks passed.
ℹ️ ✓ [valid-refs] All file references across 1 skill(s) are valid.
ℹ️ ✓ valid-refs: All file references resolve to existing files within the skill directory.
ℹ️ 1 skill(s) linted, 1 passed
Full linter output
### Linting skills/speak-summary
✅ speak-summary (2/2 checks passed)
    ✓ [spec-compliance] All 1 skill(s) are spec-compliant.
        ✓ spec-compliance: All spec checks passed.
    ✓ [valid-refs] All file references across 1 skill(s) are valid.
        ✓ valid-refs: All file references resolve to existing files within the skill directory.

1 skill(s) linted, 1 passed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-tts synthesis, 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
aaronpowell merged commit 18f06eb into github:main Aug 27, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-submission PR adds at least one new contribution skills PR touches skills

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants