@friendlyrobot/discord-pi-agent 0.19.15 → 0.19.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
1
  import type { Message } from "discord.js";
2
- export declare function addWorkingReaction(message: Message): Promise<void>;
3
- export declare function removeWorkingReaction(message: Message): Promise<void>;
2
+ export declare const DEFAULT_WORKING_EMOJI = "\u2699\uFE0F";
3
+ export declare function addWorkingReaction(message: Message, emoji?: string): Promise<void>;
4
+ export declare function removeWorkingReaction(message: Message, emoji?: string): Promise<void>;
4
5
  export declare function sendReply(message: Message, text: string): Promise<void>;
5
6
  /**
6
7
  * Sends a command response wrapped in triple backticks.
package/dist/index.js CHANGED
@@ -727,6 +727,7 @@ async function handleHelpCommand(trimmedInput, context) {
727
727
  "!compact - compact the persistent session",
728
728
  "!reset-session - start a fresh persistent session",
729
729
  "!reload - reload resources (AGENTS.md, extensions, skills, etc.)",
730
+ "!reaction - show or set the working reaction emoji",
730
731
  extraCommands,
731
732
  "Any other text goes to the agent session."
732
733
  ].filter(Boolean).join(`
@@ -887,6 +888,32 @@ async function handleResetSessionCommand(trimmedInput, context) {
887
888
  })
888
889
  };
889
890
  }
891
+ async function handleReactionCommand(trimmedInput, _context) {
892
+ if (trimmedInput !== "!reaction" && !trimmedInput.startsWith("!reaction ")) {
893
+ return null;
894
+ }
895
+ const parts = trimmedInput.split(" ");
896
+ if (parts.length === 1) {
897
+ return {
898
+ handled: true,
899
+ response: `Current working reaction: ${_context.workingEmoji}
900
+ ` + `Usage: !reaction <emoji> to change it.
901
+ ` + `Examples: !reaction \uD83D\uDD04 or !reaction ⏳`
902
+ };
903
+ }
904
+ const emoji = parts.slice(1).join(" ").trim();
905
+ if (!emoji) {
906
+ return {
907
+ handled: true,
908
+ response: "Please provide an emoji. Example: !reaction \uD83D\uDD04"
909
+ };
910
+ }
911
+ return {
912
+ handled: true,
913
+ workingEmoji: emoji,
914
+ response: `Working reaction emoji set to ${emoji}`
915
+ };
916
+ }
890
917
  var commandHandlers = [
891
918
  handleHelpCommand,
892
919
  handleArchiveCommand,
@@ -895,7 +922,8 @@ var commandHandlers = [
895
922
  handleModelCommand,
896
923
  handleCompactCommand,
897
924
  handleReloadCommand,
898
- handleResetSessionCommand
925
+ handleResetSessionCommand,
926
+ handleReactionCommand
899
927
  ];
900
928
  async function executeSessionCommand(input, context) {
901
929
  const trimmedInput = input.trim();
@@ -1150,17 +1178,17 @@ function chunkByLines(text, maxSize) {
1150
1178
  }
1151
1179
  return chunks;
1152
1180
  }
1153
- var WORKING_EMOJI = "⚙️";
1154
- async function addWorkingReaction(message) {
1181
+ var DEFAULT_WORKING_EMOJI = "⚙️";
1182
+ async function addWorkingReaction(message, emoji = DEFAULT_WORKING_EMOJI) {
1155
1183
  try {
1156
- await message.react(WORKING_EMOJI);
1184
+ await message.react(emoji);
1157
1185
  } catch (error) {
1158
1186
  logger7.debug({ messageId: message.id, error }, "failed to add working reaction");
1159
1187
  }
1160
1188
  }
1161
- async function removeWorkingReaction(message) {
1189
+ async function removeWorkingReaction(message, emoji = DEFAULT_WORKING_EMOJI) {
1162
1190
  try {
1163
- const reaction = message.reactions.cache.get(WORKING_EMOJI);
1191
+ const reaction = message.reactions.cache.get(emoji);
1164
1192
  if (reaction) {
1165
1193
  await reaction.users.remove(message.client.user);
1166
1194
  }
@@ -1585,10 +1613,15 @@ ${attachment.content}`;
1585
1613
  const commandResult = await executeSessionCommand(content, {
1586
1614
  agentService,
1587
1615
  promptQueue,
1588
- session
1616
+ session,
1617
+ workingEmoji: entry.workingEmoji
1589
1618
  });
1590
1619
  if (commandResult.handled) {
1591
1620
  stopTypingForChannel(channelKey);
1621
+ if (commandResult.workingEmoji) {
1622
+ entry.workingEmoji = commandResult.workingEmoji;
1623
+ logger11.info({ scope, emoji: commandResult.workingEmoji }, "working emoji updated");
1624
+ }
1592
1625
  if (commandResult.archive && scope.startsWith("thread:")) {
1593
1626
  logger11.info({ scope }, "archiving thread");
1594
1627
  const archiveChannel = message.channel;
@@ -1622,7 +1655,7 @@ ${commandResult.response ?? "Archiving..."}
1622
1655
  logger11.debug({ messageId: message.id }, "channel not sendable");
1623
1656
  return;
1624
1657
  }
1625
- await addWorkingReaction(message);
1658
+ await addWorkingReaction(message, entry.workingEmoji);
1626
1659
  const queuePosition = promptQueue.getSnapshot().pending;
1627
1660
  if (queuePosition > 0) {
1628
1661
  await sendReply(message, `Queued. ${queuePosition} request(s) ahead of this one.`);
@@ -1647,7 +1680,7 @@ ${commandResult.response ?? "Archiving..."}
1647
1680
  });
1648
1681
  } finally {
1649
1682
  stopTypingForChannel(channelKey);
1650
- await removeWorkingReaction(message);
1683
+ await removeWorkingReaction(message, entry.workingEmoji);
1651
1684
  }
1652
1685
  await sendReply(message, response);
1653
1686
  }
@@ -1768,7 +1801,8 @@ class SessionRegistry {
1768
1801
  const entry = {
1769
1802
  session,
1770
1803
  promptQueue,
1771
- createdAt: new Date
1804
+ createdAt: new Date,
1805
+ workingEmoji: DEFAULT_WORKING_EMOJI
1772
1806
  };
1773
1807
  this.scopes.set(scope, entry);
1774
1808
  logger13.debug({
@@ -6,10 +6,14 @@ export type CommandResult = {
6
6
  response?: string;
7
7
  /** Set to true when the command wants to archive the current thread. */
8
8
  archive?: boolean;
9
+ /** When set, update the session's working reaction emoji. */
10
+ workingEmoji?: string;
9
11
  };
10
12
  export type CommandContext = {
11
13
  agentService: AgentService;
12
14
  promptQueue: PromptQueue;
13
15
  session?: AgentSession;
16
+ /** Current working reaction emoji for this session. */
17
+ workingEmoji: string;
14
18
  };
15
19
  export declare function executeSessionCommand(input: string, context: CommandContext): Promise<CommandResult>;
@@ -6,6 +6,7 @@ export type ScopedSessionEntry = {
6
6
  session: AgentSession;
7
7
  promptQueue: PromptQueue;
8
8
  createdAt: Date;
9
+ workingEmoji: string;
9
10
  };
10
11
  /**
11
12
  * Derive a deterministic session directory from a scope key.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@friendlyrobot/discord-pi-agent",
3
- "version": "0.19.15",
3
+ "version": "0.19.16",
4
4
  "description": "Reusable Discord gateway for persistent pi agent sessions",
5
5
  "license": "MIT",
6
6
  "type": "module",