Add isolated Remote speech synthesis and typed rendering

Preserve literal whitespace and resolved spelling/language state across complete Remote speech assemblies. Isolate cancellation from local status and echo, retire handles on configuration changes or rendering failure, and cover metadata preparation cancellation with private SSIP fixtures.

Verified focused application and backend race tests, ten repetitions of isolated-client/rendering cases, shared speech regressions, affected-package vet, reader build and Tentacles checks. Incoming mailbox integration, local priority and live audible acceptance remain pending.
This commit is contained in:
ak47 committed 2026-11-04 19:56:38 -05:00
1 parent 622d2f96a1
commit ac431dd514
9 files changed
+1370 -11

No files matched your search

+7
View File
@@ -293,6 +293,12 @@ func (client *Client) speak(ctx context.Context, text string) (result error) {
if err != nil {
return err
}
return client.speak_block(ctx, text)
}
// text is validated by the caller. Dot escaping applies to every data line,
// including lines containing what would otherwise be the SSIP terminator.
func (client *Client) speak_block(ctx context.Context, text string) (result error) {
if client.conn == nil {
return errors.New("speech client is not connected")
@@ -315,6 +321,7 @@ func (client *Client) speak(ctx context.Context, text string) (result error) {
if strings.HasPrefix(text, ".") {
text = "." + text
}
text = strings.ReplaceAll(text, "\r\n.", "\r\n..")
request := "SPEAK\r\n" + text + "\r\n.\r\n"
if _, err := client.conn.Write([]byte(request)); err != nil {
return fmt.Errorf("send speech block: %w", err)