





















@@ -17,9 +17,102 @@ import {
1717resolveAgentComponentRoute,
1818resolveInteractionContextWithDmAuth,
1919type AgentComponentContext,
20+type AgentComponentMessageInteraction,
2021} from "./agent-components-helpers.js";
2122import { enqueueSystemEvent } from "./agent-components.deps.runtime.js";
222324+type AgentSystemControlParams = {
25+ctx: AgentComponentContext;
26+interaction: AgentComponentMessageInteraction;
27+data: ComponentData;
28+label: string;
29+interactionComponentLabel: string;
30+authorizationComponentLabel: string;
31+invalidReply: string;
32+unauthorizedReply: string;
33+contextKeyPrefix: string;
34+formatEventText: (params: { componentId: string; username: string; userId: string }) => string;
35+};
36+37+async function runAgentSystemControlInteraction(params: AgentSystemControlParams): Promise<void> {
38+const parsed = parseAgentComponentData(params.data);
39+if (!parsed) {
40+logError(`${params.label}: failed to parse component data`);
41+try {
42+await params.interaction.reply({
43+content: params.invalidReply,
44+ephemeral: true,
45+});
46+} catch {
47+// Interaction may have expired
48+}
49+return;
50+}
51+52+const { componentId } = parsed;
53+const interactionCtx = await resolveInteractionContextWithDmAuth({
54+ctx: params.ctx,
55+interaction: params.interaction,
56+label: params.label,
57+componentLabel: params.interactionComponentLabel,
58+defer: false,
59+});
60+if (!interactionCtx) {
61+return;
62+}
63+const {
64+ channelId,
65+ user,
66+ username,
67+ userId,
68+ replyOpts,
69+ rawGuildId,
70+ isDirectMessage,
71+ isGroupDm,
72+ memberRoleIds,
73+} = interactionCtx;
74+75+const allowed = await ensureAgentComponentInteractionAllowed({
76+ctx: params.ctx,
77+interaction: params.interaction,
78+ channelId,
79+ rawGuildId,
80+ memberRoleIds,
81+ user,
82+ replyOpts,
83+componentLabel: params.authorizationComponentLabel,
84+unauthorizedReply: params.unauthorizedReply,
85+});
86+if (!allowed) {
87+return;
88+}
89+90+const route = resolveAgentComponentRoute({
91+ctx: params.ctx,
92+ rawGuildId,
93+ memberRoleIds,
94+ isDirectMessage,
95+ isGroupDm,
96+ userId,
97+ channelId,
98+parentId: allowed.parentId,
99+});
100+101+const eventText = params.formatEventText({ componentId, username, userId });
102+logDebug(`${params.label}: enqueuing event for channel ${channelId}: ${eventText}`);
103+104+enqueueSystemEvent(eventText, {
105+sessionKey: route.sessionKey,
106+contextKey: `${params.contextKeyPrefix}:${channelId}:${componentId}:${userId}`,
107+});
108+109+await ackComponentInteraction({
110+interaction: params.interaction,
111+ replyOpts,
112+label: params.label,
113+});
114+}
115+23116export class AgentComponentButton extends Button {
24117override label = AGENT_BUTTON_KEY;
25118customId = `${AGENT_BUTTON_KEY}:seed=1`;
@@ -32,81 +125,19 @@ export class AgentComponentButton extends Button {
32125}
3312634127override async run(interaction: ButtonInteraction, data: ComponentData): Promise<void> {
35-const parsed = parseAgentComponentData(data);
36-if (!parsed) {
37-logError("agent button: failed to parse component data");
38-try {
39-await interaction.reply({
40-content: "This button is no longer valid.",
41-ephemeral: true,
42-});
43-} catch {
44-// Interaction may have expired
45-}
46-return;
47-}
48-49-const { componentId } = parsed;
50-51-const interactionCtx = await resolveInteractionContextWithDmAuth({
128+await runAgentSystemControlInteraction({
52129ctx: this.ctx,
53130 interaction,
131+ data,
54132label: "agent button",
55-componentLabel: "button",
56-defer: false,
57-});
58-if (!interactionCtx) {
59-return;
60-}
61-const {
62- channelId,
63- user,
64- username,
65- userId,
66- replyOpts,
67- rawGuildId,
68- isDirectMessage,
69- isGroupDm,
70- memberRoleIds,
71-} = interactionCtx;
72-73-const allowed = await ensureAgentComponentInteractionAllowed({
74-ctx: this.ctx,
75- interaction,
76- channelId,
77- rawGuildId,
78- memberRoleIds,
79- user,
80- replyOpts,
81-componentLabel: "button",
133+interactionComponentLabel: "button",
134+authorizationComponentLabel: "button",
135+invalidReply: "This button is no longer valid.",
82136unauthorizedReply: "You are not authorized to use this button.",
137+contextKeyPrefix: "discord:agent-button",
138+formatEventText: ({ componentId, username, userId }) =>
139+`[Discord component: ${componentId} clicked by ${username} (${userId})]`,
83140});
84-if (!allowed) {
85-return;
86-}
87-const { parentId } = allowed;
88-89-const route = resolveAgentComponentRoute({
90-ctx: this.ctx,
91- rawGuildId,
92- memberRoleIds,
93- isDirectMessage,
94- isGroupDm,
95- userId,
96- channelId,
97- parentId,
98-});
99-100-const eventText = `[Discord component: ${componentId} clicked by ${username} (${userId})]`;
101-102-logDebug(`agent button: enqueuing event for channel ${channelId}: ${eventText}`);
103-104-enqueueSystemEvent(eventText, {
105-sessionKey: route.sessionKey,
106-contextKey: `discord:agent-button:${channelId}:${componentId}:${userId}`,
107-});
108-109-await ackComponentInteraction({ interaction, replyOpts, label: "agent button" });
110141}
111142}
112143@@ -121,84 +152,21 @@ export class AgentSelectMenu extends StringSelectMenu {
121152}
122153123154override async run(interaction: StringSelectMenuInteraction, data: ComponentData): Promise<void> {
124-const parsed = parseAgentComponentData(data);
125-if (!parsed) {
126-logError("agent select: failed to parse component data");
127-try {
128-await interaction.reply({
129-content: "This select menu is no longer valid.",
130-ephemeral: true,
131-});
132-} catch {
133-// Interaction may have expired
134-}
135-return;
136-}
137-138-const { componentId } = parsed;
139-140-const interactionCtx = await resolveInteractionContextWithDmAuth({
155+const values = interaction.values ?? [];
156+const valuesText = values.length > 0 ? ` (selected: ${values.join(", ")})` : "";
157+await runAgentSystemControlInteraction({
141158ctx: this.ctx,
142159 interaction,
160+ data,
143161label: "agent select",
144-componentLabel: "select menu",
145-defer: false,
146-});
147-if (!interactionCtx) {
148-return;
149-}
150-const {
151- channelId,
152- user,
153- username,
154- userId,
155- replyOpts,
156- rawGuildId,
157- isDirectMessage,
158- isGroupDm,
159- memberRoleIds,
160-} = interactionCtx;
161-162-const allowed = await ensureAgentComponentInteractionAllowed({
163-ctx: this.ctx,
164- interaction,
165- channelId,
166- rawGuildId,
167- memberRoleIds,
168- user,
169- replyOpts,
170-componentLabel: "select",
162+interactionComponentLabel: "select menu",
163+authorizationComponentLabel: "select",
164+invalidReply: "This select menu is no longer valid.",
171165unauthorizedReply: "You are not authorized to use this select menu.",
166+contextKeyPrefix: "discord:agent-select",
167+formatEventText: ({ componentId, username, userId }) =>
168+`[Discord select menu: ${componentId} interacted by ${username} (${userId})${valuesText}]`,
172169});
173-if (!allowed) {
174-return;
175-}
176-const { parentId } = allowed;
177-178-const values = interaction.values ?? [];
179-const valuesText = values.length > 0 ? ` (selected: ${values.join(", ")})` : "";
180-181-const route = resolveAgentComponentRoute({
182-ctx: this.ctx,
183- rawGuildId,
184- memberRoleIds,
185- isDirectMessage,
186- isGroupDm,
187- userId,
188- channelId,
189- parentId,
190-});
191-192-const eventText = `[Discord select menu: ${componentId} interacted by ${username} (${userId})${valuesText}]`;
193-194-logDebug(`agent select: enqueuing event for channel ${channelId}: ${eventText}`);
195-196-enqueueSystemEvent(eventText, {
197-sessionKey: route.sessionKey,
198-contextKey: `discord:agent-select:${channelId}:${componentId}:${userId}`,
199-});
200-201-await ackComponentInteraction({ interaction, replyOpts, label: "agent select" });
202170}
203171}
204172此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。