// enhance.go implements audio.SpeechEnhancementProvider against a // DeepFilterNet shim (audioutils) reached through llama-swap's /upstream // passthrough (ADR-0024): // // POST /upstream//v1/enhance multipart file -> WAV package llamaswap import ( "context" "fmt" "net/http" "gitea.stevedudenhoeffer.com/steve/majordomo/audio" "gitea.stevedudenhoeffer.com/steve/majordomo/llm" ) // SpeechEnhancerModel implements audio.SpeechEnhancementProvider. The id // selects which upstream llama-swap loads. func (p *Provider) SpeechEnhancerModel(id string, opts ...audio.SpeechEnhancerModelOption) (audio.SpeechEnhancer, error) { if err := p.requireBaseURL(); err != nil { return nil, err } _ = audio.ApplySpeechEnhancerModelOptions(opts) return &speechEnhancerModel{p: p, id: id}, nil } type speechEnhancerModel struct { p *Provider id string } // Enhance implements audio.SpeechEnhancer. The endpoint always answers WAV. func (m *speechEnhancerModel) Enhance(ctx context.Context, req audio.EnhancementRequest, opts ...audio.EnhancementOption) (*audio.SpeechResult, error) { req = req.Apply(opts...) if len(req.Audio) == 0 { return nil, fmt.Errorf("%w: speech enhancement requires audio bytes", llm.ErrUnsupported) } path, err := upstreamPath(m.id, "/v1/enhance") if err != nil { return nil, err } body, contentType, err := buildMultipart("build enhance form", filePart{field: "file", filename: transcriptionFilename(req.Filename, req.MIME), data: req.Audio}, nil) if err != nil { return nil, err } raw, respType, err := m.p.doRaw(ctx, http.MethodPost, path, m.id, contentType, body, maxAudioResponseBytes) if err != nil { return nil, err } if len(raw) == 0 { return nil, &llm.APIError{Provider: m.p.name, Model: m.id, Message: "enhance response contained no audio"} } mimeType := audioResultMIME(respType, raw) if mimeType == "" { return nil, &llm.APIError{Provider: m.p.name, Model: m.id, Message: fmt.Sprintf("enhance response is not audio (Content-Type %q): %s", respType, truncateForError(raw))} } return &audio.SpeechResult{Audio: raw, MIME: mimeType}, nil }