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)
|
||||
}
|
||||
|
||||
// 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)
|
||||
if cfg.Tools.IsToolEnabled("send_file") {
|
||||
sendFileTool := tools.NewSendFileTool(
|
||||
|
|
|
|||
|
|
@ -10,8 +10,10 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sipeed/picoclaw/pkg/config"
|
||||
"github.com/sipeed/picoclaw/pkg/logger"
|
||||
"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 {
|
||||
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.
|
||||
type VoiceControl struct {
|
||||
SessionID string `json:"session_id"`
|
||||
ChatID string `json:"chat_id"`
|
||||
Type string `json:"type"` // "state", "command"
|
||||
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})
|
||||
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 {
|
||||
s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("Failed to join voice channel: %v", err))
|
||||
return true
|
||||
|
|
@ -34,6 +35,7 @@ func (c *DiscordChannel) handleVoiceCommand(s *discordgo.Session, m *discordgo.M
|
|||
} else if m.Content == "!vc leave" {
|
||||
vc, exists := s.VoiceConnections[m.GuildID]
|
||||
if exists && vc != nil {
|
||||
vc.Disconnect(c.ctx)
|
||||
vc.Disconnect(c.ctx)
|
||||
s.ChannelMessageSend(m.ChannelID, "Left Voice Channel.")
|
||||
} 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,
|
||||
ChatID: acc.chatID,
|
||||
Content: res.Text + oralPrompt,
|
||||
Content: res.Text + oralPrompt,
|
||||
Peer: bus.Peer{Kind: "channel", ID: acc.chatID},
|
||||
Metadata: map[string]string{
|
||||
"is_voice": "true",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue