feat(discord): include channel name in dynamic context
This commit is contained in:
parent
9222351871
commit
621836cbe9
4 changed files with 63 additions and 1 deletions
|
|
@ -55,6 +55,7 @@ type processOptions struct {
|
|||
SessionKey string // Session identifier for history/context
|
||||
Channel string // Target channel for tool execution
|
||||
ChatID string // Target chat ID for tool execution
|
||||
ChatName string // Optional human-readable chat name for prompt context
|
||||
UserMessage string // User message content (may include prefix)
|
||||
Media []string // media:// refs from inbound message
|
||||
DefaultResponse string // Response when LLM returns empty
|
||||
|
|
@ -67,6 +68,7 @@ const (
|
|||
defaultResponse = "I've completed processing but have no response to give. Increase `max_tool_iterations` in config.json."
|
||||
sessionKeyAgentPrefix = "agent:"
|
||||
metadataKeyAccountID = "account_id"
|
||||
metadataKeyChatName = "chat_name"
|
||||
metadataKeyGuildID = "guild_id"
|
||||
metadataKeyTeamID = "team_id"
|
||||
metadataKeyParentPeerKind = "parent_peer_kind"
|
||||
|
|
@ -619,6 +621,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
|||
SessionKey: sessionKey,
|
||||
Channel: msg.Channel,
|
||||
ChatID: msg.ChatID,
|
||||
ChatName: inboundMetadata(msg, metadataKeyChatName),
|
||||
UserMessage: msg.Content,
|
||||
Media: msg.Media,
|
||||
DefaultResponse: defaultResponse,
|
||||
|
|
@ -761,7 +764,7 @@ func (al *AgentLoop) runAgentLoop(
|
|||
opts.UserMessage,
|
||||
opts.Media,
|
||||
opts.Channel,
|
||||
opts.ChatID,
|
||||
displayChatID(opts.ChatID, opts.ChatName),
|
||||
)
|
||||
|
||||
// Resolve media:// refs to base64 data URLs (streaming)
|
||||
|
|
@ -1818,6 +1821,13 @@ func inboundMetadata(msg bus.InboundMessage, key string) string {
|
|||
return msg.Metadata[key]
|
||||
}
|
||||
|
||||
func displayChatID(chatID, chatName string) string {
|
||||
if chatID == "" || chatName == "" {
|
||||
return chatID
|
||||
}
|
||||
return fmt.Sprintf("%s (%s)", chatID, chatName)
|
||||
}
|
||||
|
||||
// extractParentPeer extracts the parent peer (reply-to) from inbound message metadata.
|
||||
func extractParentPeer(msg bus.InboundMessage) *routing.RoutePeer {
|
||||
parentKind := inboundMetadata(msg, metadataKeyParentPeerKind)
|
||||
|
|
|
|||
|
|
@ -889,6 +889,16 @@ func TestTargetReasoningChannelID_AllChannels(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDisplayChatID_AppendsChatName(t *testing.T) {
|
||||
if got := displayChatID("123456789012345678", "#general"); got != "123456789012345678 (#general)" {
|
||||
t.Fatalf("displayChatID() = %q, want %q", got, "123456789012345678 (#general)")
|
||||
}
|
||||
|
||||
if got := displayChatID("123456789012345678", ""); got != "123456789012345678" {
|
||||
t.Fatalf("displayChatID() without chatName = %q, want %q", got, "123456789012345678")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleReasoning(t *testing.T) {
|
||||
newLoop := func(t *testing.T) (*AgentLoop, *bus.MessageBus) {
|
||||
t.Helper()
|
||||
|
|
|
|||
|
|
@ -449,12 +449,31 @@ func (c *DiscordChannel) handleMessage(s *discordgo.Session, m *discordgo.Messag
|
|||
"display_name": sender.DisplayName,
|
||||
"guild_id": m.GuildID,
|
||||
"channel_id": m.ChannelID,
|
||||
"chat_name": resolveDiscordChannelName(c.session, m.ChannelID),
|
||||
"is_dm": fmt.Sprintf("%t", m.GuildID == ""),
|
||||
}
|
||||
|
||||
c.HandleMessage(c.ctx, peer, m.ID, senderID, m.ChannelID, content, mediaPaths, metadata, sender)
|
||||
}
|
||||
|
||||
func resolveDiscordChannelName(session *discordgo.Session, channelID string) string {
|
||||
if session == nil || channelID == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if session.State != nil {
|
||||
if channel, err := session.State.Channel(channelID); err == nil && channel != nil && channel.Name != "" {
|
||||
return "#" + channel.Name
|
||||
}
|
||||
}
|
||||
|
||||
channel, err := session.Channel(channelID)
|
||||
if err != nil || channel == nil || channel.Name == "" {
|
||||
return ""
|
||||
}
|
||||
return "#" + channel.Name
|
||||
}
|
||||
|
||||
// startTyping starts a continuous typing indicator loop for the given chatID.
|
||||
// It stops any existing typing loop for that chatID before starting a new one.
|
||||
func (c *DiscordChannel) startTyping(chatID string) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package discord
|
|||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
func TestChannelRefRegex(t *testing.T) {
|
||||
|
|
@ -96,3 +98,24 @@ func TestMsgLinkRegex_MultipleMatches(t *testing.T) {
|
|||
t.Errorf("3rd match = %v, want guild=7 chan=8 msg=9", matches[2])
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveDiscordChannelName_FromState(t *testing.T) {
|
||||
session, err := discordgo.New("Bot test-token")
|
||||
if err != nil {
|
||||
t.Fatalf("discordgo.New() error = %v", err)
|
||||
}
|
||||
|
||||
session.StateEnabled = true
|
||||
session.State = discordgo.NewState()
|
||||
session.State.GuildAdd(&discordgo.Guild{ID: "guild-1"})
|
||||
session.State.ChannelAdd(&discordgo.Channel{
|
||||
ID: "123",
|
||||
Name: "general",
|
||||
Type: discordgo.ChannelTypeGuildText,
|
||||
GuildID: "guild-1",
|
||||
})
|
||||
|
||||
if got := resolveDiscordChannelName(session, "123"); got != "#general" {
|
||||
t.Fatalf("resolveDiscordChannelName() = %q, want %q", got, "#general")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue