feat: unify provider history context
This commit is contained in:
@@ -38,6 +38,11 @@ import {
|
||||
buildMentionRegexes,
|
||||
matchesMentionPatterns,
|
||||
} from "../auto-reply/reply/mentions.js";
|
||||
import {
|
||||
appendHistoryEntry,
|
||||
buildHistoryContextFromEntries,
|
||||
type HistoryEntry,
|
||||
} from "../auto-reply/reply/history.js";
|
||||
import {
|
||||
createReplyDispatcher,
|
||||
createReplyDispatcherWithTyping,
|
||||
@@ -117,14 +122,6 @@ type DiscordSnapshotMessage = {
|
||||
type DiscordMessageSnapshot = {
|
||||
message?: DiscordSnapshotMessage | null;
|
||||
};
|
||||
|
||||
type DiscordHistoryEntry = {
|
||||
sender: string;
|
||||
body: string;
|
||||
timestamp?: number;
|
||||
messageId?: string;
|
||||
};
|
||||
|
||||
type DiscordReactionEvent = Parameters<MessageReactionAddListener["handle"]>[0];
|
||||
type DiscordThreadChannel = {
|
||||
id: string;
|
||||
@@ -392,7 +389,10 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
||||
const textLimit = resolveTextChunkLimit(cfg, "discord", account.accountId);
|
||||
const historyLimit = Math.max(
|
||||
0,
|
||||
opts.historyLimit ?? discordCfg.historyLimit ?? 20,
|
||||
opts.historyLimit ??
|
||||
discordCfg.historyLimit ??
|
||||
cfg.messages?.groupChat?.historyLimit ??
|
||||
20,
|
||||
);
|
||||
const replyToMode = opts.replyToMode ?? discordCfg.replyToMode ?? "off";
|
||||
const dmEnabled = dmConfig?.enabled ?? true;
|
||||
@@ -459,7 +459,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
||||
);
|
||||
|
||||
const logger = getChildLogger({ module: "discord-auto-reply" });
|
||||
const guildHistories = new Map<string, DiscordHistoryEntry[]>();
|
||||
const guildHistories = new Map<string, HistoryEntry[]>();
|
||||
let botUserId: string | undefined;
|
||||
|
||||
if (nativeDisabledExplicit) {
|
||||
@@ -604,7 +604,7 @@ export function createDiscordMessageHandler(params: {
|
||||
token: string;
|
||||
runtime: RuntimeEnv;
|
||||
botUserId?: string;
|
||||
guildHistories: Map<string, DiscordHistoryEntry[]>;
|
||||
guildHistories: Map<string, HistoryEntry[]>;
|
||||
historyLimit: number;
|
||||
mediaMaxBytes: number;
|
||||
textLimit: number;
|
||||
@@ -888,19 +888,21 @@ export function createDiscordMessageHandler(params: {
|
||||
includeForwarded: true,
|
||||
});
|
||||
if (isGuildMessage && historyLimit > 0 && textForHistory) {
|
||||
const history = guildHistories.get(message.channelId) ?? [];
|
||||
history.push({
|
||||
sender:
|
||||
data.member?.nickname ??
|
||||
author.globalName ??
|
||||
author.username ??
|
||||
author.id,
|
||||
body: textForHistory,
|
||||
timestamp: resolveTimestampMs(message.timestamp),
|
||||
messageId: message.id,
|
||||
appendHistoryEntry({
|
||||
historyMap: guildHistories,
|
||||
historyKey: message.channelId,
|
||||
limit: historyLimit,
|
||||
entry: {
|
||||
sender:
|
||||
data.member?.nickname ??
|
||||
author.globalName ??
|
||||
author.username ??
|
||||
author.id,
|
||||
body: textForHistory,
|
||||
timestamp: resolveTimestampMs(message.timestamp),
|
||||
messageId: message.id,
|
||||
},
|
||||
});
|
||||
while (history.length > historyLimit) history.shift();
|
||||
guildHistories.set(message.channelId, history);
|
||||
}
|
||||
|
||||
const shouldRequireMention =
|
||||
@@ -1049,21 +1051,17 @@ export function createDiscordMessageHandler(params: {
|
||||
if (!isDirectMessage) {
|
||||
const history =
|
||||
historyLimit > 0 ? (guildHistories.get(message.channelId) ?? []) : [];
|
||||
const historyWithoutCurrent =
|
||||
history.length > 0 ? history.slice(0, -1) : [];
|
||||
if (historyWithoutCurrent.length > 0) {
|
||||
const historyText = historyWithoutCurrent
|
||||
.map((entry) =>
|
||||
formatAgentEnvelope({
|
||||
provider: "Discord",
|
||||
from: fromLabel,
|
||||
timestamp: entry.timestamp,
|
||||
body: `${entry.sender}: ${entry.body} [id:${entry.messageId ?? "unknown"} channel:${message.channelId}]`,
|
||||
}),
|
||||
)
|
||||
.join("\n");
|
||||
combinedBody = `[Chat messages since your last reply - for context]\n${historyText}\n\n[Current message - respond to this]\n${combinedBody}`;
|
||||
}
|
||||
combinedBody = buildHistoryContextFromEntries({
|
||||
entries: history,
|
||||
currentMessage: combinedBody,
|
||||
formatEntry: (entry) =>
|
||||
formatAgentEnvelope({
|
||||
provider: "Discord",
|
||||
from: fromLabel,
|
||||
timestamp: entry.timestamp,
|
||||
body: `${entry.sender}: ${entry.body} [id:${entry.messageId ?? "unknown"} channel:${message.channelId}]`,
|
||||
}),
|
||||
});
|
||||
const name = formatDiscordUserTag(author);
|
||||
const id = author.id;
|
||||
combinedBody = `${combinedBody}\n[from: ${name} user id:${id}]`;
|
||||
@@ -1116,6 +1114,7 @@ export function createDiscordMessageHandler(params: {
|
||||
const ctxPayload = {
|
||||
Body: combinedBody,
|
||||
RawBody: baseText,
|
||||
CommandBody: baseText,
|
||||
From: isDirectMessage
|
||||
? `discord:${author.id}`
|
||||
: `group:${message.channelId}`,
|
||||
@@ -1649,6 +1648,7 @@ function createDiscordNativeCommand(params: {
|
||||
});
|
||||
const ctxPayload = {
|
||||
Body: prompt,
|
||||
CommandBody: prompt,
|
||||
From: isDirectMessage ? `discord:${user.id}` : `group:${channelId}`,
|
||||
To: `slash:${user.id}`,
|
||||
SessionKey: `agent:${route.agentId}:${sessionPrefix}:${user.id}`,
|
||||
|
||||
Reference in New Issue
Block a user