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.SetExtension. Request has no arbitrary parameter bag. Streamer is separate from Model so consumers only require streaming from implementations that actually support it.
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 ¶
This section is empty.
Variables ¶
Functions ¶
This section is empty.
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. Call implementations validate requests before I/O, reject explicit options they cannot represent, preserve context error identity, and return responses that pass Validate.
type ModelFunc ¶
ModelFunc lets an ordinary function satisfy Model without declaring a named type, which is what keeps middleware and test doubles from each inventing their own adapter.
type Options ¶
type Options struct {
// Model is the provider model identifier (e.g. "tts-1").
Model string `json:"model"`
// Voice selects the speaker profile. Provider-specific values.
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 speed.
Speed float64 `json:"speed"`
// Extensions carries JSON-safe provider-specific options unknown to this
// struct.
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) 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 carries per-chunk extras.
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) MarshalJSON ¶
func (*Output) UnmarshalJSON ¶
type Request ¶
type Request struct {
// Text is the prompt converted to speech.
Text string `json:"text"`
Options Options `json:"options,omitzero"`
}
Request is one TTS call: the input text and explicit options.
func NewRequest ¶
NewRequest validates the required input while leaving per-call options at their portable zero defaults.
func (Request) MarshalJSON ¶
func (*Request) UnmarshalJSON ¶
type Response ¶
type Response struct {
// Output holds the generated audio. Non-nil after [NewResponse].
Output *Output `json:"output,omitempty"`
// Metadata carries shared response-level fields.
Metadata *ResponseMetadata `json:"metadata,omitempty"`
}
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 NewResponse ¶
func NewResponse(output *Output, responseMetadata *ResponseMetadata) (*Response, error)
NewResponse validates a complete provider result at the protocol boundary.
func (Response) MarshalJSON ¶
func (*Response) UnmarshalJSON ¶
type ResponseMetadata ¶
type ResponseMetadata struct {
// Model is the model name actually served.
Model string `json:"model"`
// CreatedAt is the provider-reported creation timestamp.
CreatedAt time.Time `json:"created_at,omitzero"`
// Extra carries JSON-safe provider-specific metadata.
Extra metadata.Map `json:"extra,omitzero"`
}
ResponseMetadata holds response-level metadata for a TTS call.
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.
type StreamerFunc ¶
StreamerFunc is the Streamer counterpart of ModelFunc. Speech carries one because synthesis is the only non-chat modality whose output is consumed while it is still being produced.