update with corrent transcriber and leave_tool
This commit is contained in:
parent
e49f65a2be
commit
652bb6bd4c
6 changed files with 77 additions and 0 deletions
|
|
@ -246,6 +246,9 @@ func registerSharedTools(
|
||||||
agent.Tools.Register(messageTool)
|
agent.Tools.Register(messageTool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always register Voice Leave Tool (it inherently checks if channel == "discord")
|
||||||
|
agent.Tools.Register(tools.NewVoiceLeaveTool(msgBus))
|
||||||
|
|
||||||
// Send file tool (outbound media via MediaStore — store injected later by SetMediaStore)
|
// Send file tool (outbound media via MediaStore — store injected later by SetMediaStore)
|
||||||
if cfg.Tools.IsToolEnabled("send_file") {
|
if cfg.Tools.IsToolEnabled("send_file") {
|
||||||
sendFileTool := tools.NewSendFileTool(
|
sendFileTool := tools.NewSendFileTool(
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,10 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/sipeed/picoclaw/pkg/config"
|
||||||
"github.com/sipeed/picoclaw/pkg/logger"
|
"github.com/sipeed/picoclaw/pkg/logger"
|
||||||
"github.com/sipeed/picoclaw/pkg/utils"
|
"github.com/sipeed/picoclaw/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
@ -166,3 +168,19 @@ func (t *GroqTranscriber) doRequest(ctx context.Context, requestBody *bytes.Buff
|
||||||
func (t *GroqTranscriber) Name() string {
|
func (t *GroqTranscriber) Name() string {
|
||||||
return "groq"
|
return "groq"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DetectTranscriber inspects cfg and returns the appropriate Transcriber, or
|
||||||
|
// nil if no supported transcription provider is configured.
|
||||||
|
func DetectTranscriber(cfg *config.Config) Transcriber {
|
||||||
|
// Direct Groq provider config takes priority.
|
||||||
|
if key := cfg.Providers.Groq.APIKey; key != "" {
|
||||||
|
return NewGroqTranscriber(key)
|
||||||
|
}
|
||||||
|
// Fall back to any model-list entry that uses the groq/ protocol or is explicitly named groq.
|
||||||
|
for _, mc := range cfg.ModelList {
|
||||||
|
if (strings.HasPrefix(mc.Model, "groq/") || mc.ModelName == "groq" || mc.Model == "whisper-large-v3-turbo") && mc.APIKey != "" {
|
||||||
|
return NewGroqTranscriber(mc.APIKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ type AudioChunk struct {
|
||||||
// VoiceControl represents state or commands for voice sessions.
|
// VoiceControl represents state or commands for voice sessions.
|
||||||
type VoiceControl struct {
|
type VoiceControl struct {
|
||||||
SessionID string `json:"session_id"`
|
SessionID string `json:"session_id"`
|
||||||
|
ChatID string `json:"chat_id"`
|
||||||
Type string `json:"type"` // "state", "command"
|
Type string `json:"type"` // "state", "command"
|
||||||
Action string `json:"action"` // "idle", "listening", "start", "stop", "leave"
|
Action string `json:"action"` // "idle", "listening", "start", "stop", "leave"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ func (c *DiscordChannel) handleVoiceCommand(s *discordgo.Session, m *discordgo.M
|
||||||
|
|
||||||
logger.InfoCF("discord", "Joining voice channel", map[string]any{"channel": vs.ChannelID})
|
logger.InfoCF("discord", "Joining voice channel", map[string]any{"channel": vs.ChannelID})
|
||||||
vc, err := s.ChannelVoiceJoin(c.ctx, m.GuildID, vs.ChannelID, false, false)
|
vc, err := s.ChannelVoiceJoin(c.ctx, m.GuildID, vs.ChannelID, false, false)
|
||||||
|
vc, err := s.ChannelVoiceJoin(c.ctx, m.GuildID, vs.ChannelID, false, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Failed to join voice channel: %v", err))
|
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Failed to join voice channel: %v", err))
|
||||||
return true
|
return true
|
||||||
|
|
@ -34,6 +35,7 @@ func (c *DiscordChannel) handleVoiceCommand(s *discordgo.Session, m *discordgo.M
|
||||||
} else if m.Content == "!vc leave" {
|
} else if m.Content == "!vc leave" {
|
||||||
vc, exists := s.VoiceConnections[m.GuildID]
|
vc, exists := s.VoiceConnections[m.GuildID]
|
||||||
if exists && vc != nil {
|
if exists && vc != nil {
|
||||||
|
vc.Disconnect(c.ctx)
|
||||||
vc.Disconnect(c.ctx)
|
vc.Disconnect(c.ctx)
|
||||||
s.ChannelMessageSend(m.ChannelID, "Left Voice Channel.")
|
s.ChannelMessageSend(m.ChannelID, "Left Voice Channel.")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
52
pkg/tools/voice_leave.go
Normal file
52
pkg/tools/voice_leave.go
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
package tools
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/sipeed/picoclaw/pkg/bus"
|
||||||
|
"github.com/sipeed/picoclaw/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VoiceLeaveTool struct {
|
||||||
|
bus *bus.MessageBus
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewVoiceLeaveTool(mb *bus.MessageBus) *VoiceLeaveTool {
|
||||||
|
return &VoiceLeaveTool{bus: mb}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *VoiceLeaveTool) Name() string {
|
||||||
|
return "voice_leave"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *VoiceLeaveTool) Description() string {
|
||||||
|
return "Disconnects the bot from the current voice channel. Use this tool when the user says goodbye or explicitly asks you to leave the voice chat."
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *VoiceLeaveTool) Parameters() map[string]any {
|
||||||
|
return map[string]any{
|
||||||
|
"type": "object",
|
||||||
|
"properties": map[string]any{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *VoiceLeaveTool) Execute(ctx context.Context, args map[string]any) *ToolResult {
|
||||||
|
channel := ToolChannel(ctx)
|
||||||
|
chatID := ToolChatID(ctx)
|
||||||
|
|
||||||
|
if channel != "discord" {
|
||||||
|
return &ToolResult{ForLLM: "Can only leave voice channels on Discord", IsError: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.bus.PublishVoiceControl(ctx, bus.VoiceControl{
|
||||||
|
ChatID: chatID,
|
||||||
|
Type: "command",
|
||||||
|
Action: "leave",
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.InfoCF("agent", "Voice command triggered via tool: leave", map[string]any{"chat_id": chatID})
|
||||||
|
|
||||||
|
return &ToolResult{
|
||||||
|
ForLLM: "Successfully sent disconnect command to voice adapter.",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -243,6 +243,7 @@ func (a *Agent) processUtterance(ctx context.Context, acc *speechAccumulator) {
|
||||||
SenderID: acc.speakerID,
|
SenderID: acc.speakerID,
|
||||||
ChatID: acc.chatID,
|
ChatID: acc.chatID,
|
||||||
Content: res.Text + oralPrompt,
|
Content: res.Text + oralPrompt,
|
||||||
|
Content: res.Text + oralPrompt,
|
||||||
Peer: bus.Peer{Kind: "channel", ID: acc.chatID},
|
Peer: bus.Peer{Kind: "channel", ID: acc.chatID},
|
||||||
Metadata: map[string]string{
|
Metadata: map[string]string{
|
||||||
"is_voice": "true",
|
"is_voice": "true",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue