Documentation
¶
Overview ¶
Package chunkachino is a tiny, fast, pure-Go streaming chunker built for the LLM-token → TTS-chunk pipeline.
The hard invariant: Add never returns a chunk that ends mid-word. LLM providers love to split a token like ". ho" / "pe you..." across the wire; a naive chunker would flush the "." immediately and ship ". ho" to the TTS engine, producing "dot ho" / "pe you" garbage. Chunkachino waits for the next whitespace (or end-of-stream Flush) before emitting, so every chunk is guaranteed word-complete.
Three modes cover the common TTS cases:
- ModeWord: flush every N complete words at a whitespace boundary. Useful for very low-latency "talk as tokens arrive" pipelines.
- ModeSentence: flush on . ! ? at a real sentence boundary (abbreviation and decimal aware). Safety valve flushes at MaxWords if a terminator never arrives.
- ModePhrase: flush on . ! ? , ; : at a word boundary. Finer granularity for prosody in long-form TTS. Same safety valve.
Sentence/phrase mode also takes an optional MinChunkWords runt gate: a terminator on a chunk shorter than N complete words does not flush, so a lone "haha..." merges into the sentence that follows it instead of reaching the TTS engine as its own weird-prosody utterance.
The API is intentionally minimal:
c := chunkachino.New(chunkachino.Config{
Mode: chunkachino.ModeSentence,
MinWords: 3,
MaxWords: 30,
Language: "en",
})
for tok := range llmStream {
for _, chunk := range c.Add(tok) {
tts.Speak(chunk)
}
}
if tail := c.Flush(); tail != "" {
tts.Speak(tail)
}
Add returns a slice (usually empty, sometimes length 1, occasionally more) so a single large token carrying several sentences drains cleanly. This is the same shape stream2sentence and other production streaming chunkers converged on; the "one chunk per call" API reads nicer in docs but forces ugly re-entrancy in callers the first time a batched token arrives.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Chunker ¶
type Chunker struct {
// contains filtered or unexported fields
}
Chunker is a stateful streaming text chunker. NOT safe for concurrent use from multiple goroutines; each stream should own its own Chunker.
func New ¶
New returns a ready-to-use Chunker with the given config. Missing fields are filled with defaults: MinWords=5, MaxWords=30, Language="en".
func (*Chunker) Add ¶
Add feeds a token from the LLM stream into the chunker and returns any chunks that just became ready. Most tokens yield zero chunks; a token that completes a sentence/phrase/word-count boundary yields one; a single big token containing multiple complete sentences can yield several at once.
Empty tokens are a no-op and return a nil slice. Whitespace-only tokens are accepted — they often carry the boundary signal (the space after ". ").
type Config ¶
type Config struct {
// Mode selects the flush strategy.
Mode Mode
// MinWords is the minimum number of complete words a word-mode chunk
// must contain before it can flush. Ignored in sentence/phrase mode.
// Default: 5.
MinWords int
// MaxWords is the safety-valve word count in sentence/phrase mode. If
// the buffer hits this count without seeing a terminator, the chunker
// flushes at the next whitespace instead of stalling. Default: 30.
// Set to 0 to disable the safety valve (chunker will wait forever).
MaxWords int
// Language selects the abbreviation catalog. Accepted keys are the
// five Soulkyn audio locales exactly — "en-US", "es-ES", "fr-FR",
// "pt-PT", "de-DE" — plus the legacy short aliases "en" and "fr".
// Anything else falls back to English. Default: "en".
Language string
// MinChunkWords is the sentence/phrase-mode RUNT GATE: a chunk that
// reaches a terminator with fewer than this many complete words does
// NOT flush — it stays buffered and merges into the following
// sentence, so "haha..." + "You should have seen it." emit as ONE
// chunk. Built for TTS: a lone interjection ("haha...", "heh...",
// "Ah.") synthesized as its own utterance gets full sentence prosody
// and sounds wrong; grouped with its neighbor it reads naturally.
// Consecutive runts accumulate until they jointly clear the bar.
//
// The MaxWords safety valve still applies. An END-OF-STREAM runt
// still ships via Flush — there is no following sentence to merge
// into, and merging BACKWARD would mean delaying every chunk by one
// sentence, which a low-latency pipeline can't afford.
//
// 0 (default) disables the gate — pre-v0.0.2 behavior, byte-exact.
// Ignored in ModeWord (MinWords governs there).
MinChunkWords int
}
Config configures a Chunker. Zero values are filled with sensible defaults (see New).
type Mode ¶
type Mode int
Mode controls how Chunker decides when a buffered chunk is ready.
const ( // ModeWord emits at a whitespace boundary once MinWords complete words // have accumulated. Punctuation is carried along but never triggers a // flush on its own. ModeWord Mode = iota // ModeSentence emits at a sentence-ending terminator (. ! ? and unicode // equivalents) followed by whitespace, after passing abbreviation and // decimal filters. A safety valve flushes at the next whitespace once // MaxWords is exceeded so very long terminator-less runs never stall. ModeSentence // ModePhrase emits at any phrase terminator (. ! ? , ; : and unicode // equivalents) followed by whitespace. Same abbreviation, decimal, and // safety-valve rules as ModeSentence. ModePhrase )