refactor(voice): introduce Transcriber interface for pluggable STT

Currently Discord, Slack, and Telegram all hardcode *voice.GroqTranscriber
as their transcription dependency. This makes it impossible to swap in a
different STT backend without changing each channel file.

Add a Transcriber interface to pkg/voice/transcriber.go:

  type Transcriber interface {
      Transcribe(ctx context.Context, audioFilePath string) (*TranscriptionResponse, error)
      IsAvailable() bool
  }

GroqTranscriber already implements this interface (no change to its
implementation). Update Discord, Slack, and Telegram to depend on the
interface instead of the concrete type.

No behaviour change — this is a pure refactor that enables future STT
providers (e.g. local Whisper) to be dropped in without modifying channel
code.
This commit is contained in:
Myka 2026-02-17 11:09:07 +03:00
parent a961a2df87
commit 5bb3b41f1e
4 changed files with 15 additions and 6 deletions

View file

@ -24,7 +24,7 @@ type DiscordChannel struct {
*BaseChannel
session *discordgo.Session
config config.DiscordConfig
transcriber *voice.GroqTranscriber
transcriber voice.Transcriber
ctx context.Context
}
@ -45,7 +45,7 @@ func NewDiscordChannel(cfg config.DiscordConfig, bus *bus.MessageBus) (*DiscordC
}, nil
}
func (c *DiscordChannel) SetTranscriber(transcriber *voice.GroqTranscriber) {
func (c *DiscordChannel) SetTranscriber(transcriber voice.Transcriber) {
c.transcriber = transcriber
}

View file

@ -25,7 +25,7 @@ type SlackChannel struct {
api *slack.Client
socketClient *socketmode.Client
botUserID string
transcriber *voice.GroqTranscriber
transcriber voice.Transcriber
ctx context.Context
cancel context.CancelFunc
pendingAcks sync.Map
@ -58,7 +58,7 @@ func NewSlackChannel(cfg config.SlackConfig, messageBus *bus.MessageBus) (*Slack
}, nil
}
func (c *SlackChannel) SetTranscriber(transcriber *voice.GroqTranscriber) {
func (c *SlackChannel) SetTranscriber(transcriber voice.Transcriber) {
c.transcriber = transcriber
}

View file

@ -30,7 +30,7 @@ type TelegramChannel struct {
commands TelegramCommander
config *config.Config
chatIDs map[string]int64
transcriber *voice.GroqTranscriber
transcriber voice.Transcriber
placeholders sync.Map // chatID -> messageID
stopThinking sync.Map // chatID -> thinkingCancel
}
@ -80,7 +80,7 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
}, nil
}
func (c *TelegramChannel) SetTranscriber(transcriber *voice.GroqTranscriber) {
func (c *TelegramChannel) SetTranscriber(transcriber voice.Transcriber) {
c.transcriber = transcriber
}

View file

@ -16,6 +16,15 @@ import (
"github.com/sipeed/picoclaw/pkg/utils"
)
// Transcriber is the interface for speech-to-text providers.
// Any STT backend (Groq, Whisper, etc.) must implement this.
type Transcriber interface {
// Transcribe converts the audio file at audioFilePath to text.
Transcribe(ctx context.Context, audioFilePath string) (*TranscriptionResponse, error)
// IsAvailable returns true if the provider is configured and reachable.
IsAvailable() bool
}
type GroqTranscriber struct {
apiKey string
apiBase string