Documentation
¶
Overview ¶
Package speech defines the stable text-to-speech protocol and independent synchronous Model and optional Streamer provider capabilities.
NewRequest captures text and Options carries explicit voice, format, speed, and JSON-safe provider overrides written through Options.Extensions.Set. Request has no arbitrary parameter bag. Streamer is separate from Model so consumers only require streaming from implementations that actually support it. ReadChunks preserves byte ownership and read-error ordering for adapters that stream raw audio; transport lifetime stays with the adapter. Collect bounds aggregate audio before appending each chunk and discards partial output on any stream failure. A provider's Stream remains incremental; the aggregate byte budget applies to its synchronous Call.
Example ¶
package main
import (
"fmt"
"github.com/Tangerg/scope/core/speech"
)
func main() {
request, err := speech.NewRequest("Hello from Scope.")
if err != nil {
panic(err)
}
options := speech.Options{Model: "speech-model"}
err = options.Validate()
if err != nil {
panic(err)
}
options.Voice = "alloy"
options.OutputFormat = "mp3"
options.Speed = 1
request.Options = options
fmt.Println(request.Options.Model, request.Options.Voice, request.Options.Speed)
}
Output: speech-model alloy 1
Index ¶
Examples ¶
Constants ¶
const DefaultMaxAudioBytes int64 = 32 << 20
Variables ¶
Functions ¶
func ReadChunks ¶ added in v0.61.0
ReadChunks transfers independently owned bytes in read order, before any non-EOF error from the same read. EOF ends iteration without an error. Reading starts on iteration and stops when the consumer stops; the caller retains responsibility for closing the reader and governing blocked reads. A nil reader, including a typed nil, yields one error without reading.
Types ¶
type Model ¶
type Model interface {
// Call produces one complete audio response from a validated request. It
// must not retain or mutate request, transfers response ownership to the
// caller, and preserves context cancellation for errors.Is.
Call(ctx context.Context, request *Request) (*Response, error)
}
Model is the synchronous provider-neutral speech generation SPI. Implementations validate requests before I/O, reject explicit options they cannot represent, and return responses that pass Validate. Failures use github.com/Tangerg/scope/core/invocation.ClassifyFailure for evidence about the complete call. A nested failure cannot prove that earlier provider work did not run, and no failure kind authorizes retry.
type Options ¶
type Options struct {
Model string `json:"model"`
// Voice is a provider-specific speaker profile.
Voice string `json:"voice"`
// OutputFormat selects the audio container ("mp3", "wav", ...).
OutputFormat string `json:"output_format"`
// Speed scales the playback rate: 1.0 is normal and zero leaves the
// provider default.
Speed float64 `json:"speed"`
Extensions metadata.Extensions `json:"extensions,omitzero"`
}
Options holds provider-neutral text-to-speech configuration. Resolve overlays only explicitly supplied values, merges namespaced extensions, and never aliases mutable data from either input.
func (Options) JSONSchemaModel ¶ added in v0.57.0
func (Options) MarshalJSON ¶
func (*Options) UnmarshalJSON ¶
type Output ¶
type Output struct {
// Audio holds the encoded bytes in the format selected by
// Request.Options.OutputFormat.
Audio []byte `json:"audio,omitzero"`
Metadata metadata.Map `json:"metadata,omitzero"`
}
Output is one chunk of generated audio. For synchronous calls the chunk is the entire audio; for streaming calls Audio is whatever segment the provider just produced.
func (Output) JSONSchemaModel ¶ added in v0.57.0
func (Output) MarshalJSON ¶
func (*Output) UnmarshalJSON ¶
type Request ¶
func NewRequest ¶
func (Request) JSONSchemaModel ¶ added in v0.57.0
func (Request) MarshalJSON ¶
func (*Request) UnmarshalJSON ¶
type Response ¶
type Response struct {
Output *Output `json:"output,omitzero"`
Metadata *ResponseMetadata `json:"metadata,omitzero"`
}
Response is one TTS call's audio output plus shared metadata. For synchronous calls Output holds the entire audio; for streaming calls each chunk yields a Response with the just-produced segment in Output.
func Collect ¶ added in v0.61.0
Collect publishes a complete result only after the stream succeeds. It retains the terminal chunk's metadata without mutating borrowed responses.
func NewResponse ¶
func NewResponse(output *Output, responseMetadata *ResponseMetadata) (*Response, error)
func (Response) JSONSchemaModel ¶ added in v0.57.0
func (Response) MarshalJSON ¶
func (*Response) UnmarshalJSON ¶
type ResponseMetadata ¶
type ResponseMetadata struct {
Model string `json:"model"`
CreatedAt time.Time `json:"created_at,omitzero"`
Extra metadata.Map `json:"extra,omitzero"`
}
func (ResponseMetadata) JSONSchemaModel ¶ added in v0.57.0
func (ResponseMetadata) JSONSchemaModel() any
func (ResponseMetadata) MarshalJSON ¶
func (r ResponseMetadata) MarshalJSON() ([]byte, error)
func (*ResponseMetadata) UnmarshalJSON ¶
func (r *ResponseMetadata) UnmarshalJSON(data []byte) error
type Streamer ¶
type Streamer interface {
// Stream begins synthesis lazily when iterated and yields independently owned
// audio chunks in provider order. Stopping iteration releases provider
// resources synchronously; a terminal error is yielded at most once.
Stream(ctx context.Context, request *Request) iter.Seq2[*Response, error]
}
Streamer is the optional streaming capability. Every yielded response obeys the Model response contract. It is independent from Model, so callers only require streaming when they consume it.