@friendlyrobot/discord-pi-agent 0.19.15 → 0.19.17

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
@@ -324,9 +324,6 @@ async function runAgentTurn(session, prompt, options = {}) {
324
324
  const input = event.toolName === "bash" ? event.args.command : event.args;
325
325
  toolInputsByCallId.set(event.toolCallId, input);
326
326
  if (event.toolName === "bash") {
327
- logger4.debug({
328
- toolName: event.toolName
329
- }, `agent tool start: [${event.toolName}]`);
330
327
  debugPrint(input, "CMD");
331
328
  } else {
332
329
  logger4.debug({
@@ -727,6 +724,7 @@ async function handleHelpCommand(trimmedInput, context) {
727
724
  "!compact - compact the persistent session",
728
725
  "!reset-session - start a fresh persistent session",
729
726
  "!reload - reload resources (AGENTS.md, extensions, skills, etc.)",
727
+ "!reaction - show or set the working reaction emoji",
730
728
  extraCommands,
731
729
  "Any other text goes to the agent session."
732
730
  ].filter(Boolean).join(`
@@ -887,6 +885,32 @@ async function handleResetSessionCommand(trimmedInput, context) {
887
885
  })
888
886
  };
889
887
  }
888
+ async function handleReactionCommand(trimmedInput, _context) {
889
+ if (trimmedInput !== "!reaction" && !trimmedInput.startsWith("!reaction ")) {
890
+ return null;
891
+ }
892
+ const parts = trimmedInput.split(" ");
893
+ if (parts.length === 1) {
894
+ return {
895
+ handled: true,
896
+ response: `Current working reaction: ${_context.workingEmoji}
897
+ ` + `Usage: !reaction <emoji> to change it.
898
+ ` + `Examples: !reaction \uD83D\uDD04 or !reaction ⏳`
899
+ };
900
+ }
901
+ const emoji = parts.slice(1).join(" ").trim();
902
+ if (!emoji) {
903
+ return {
904
+ handled: true,
905
+ response: "Please provide an emoji. Example: !reaction \uD83D\uDD04"
906
+ };
907
+ }
908
+ return {
909
+ handled: true,
910
+ workingEmoji: emoji,
911
+ response: `Working reaction emoji set to ${emoji}`
912
+ };
913
+ }
890
914
  var commandHandlers = [
891
915
  handleHelpCommand,
892
916
  handleArchiveCommand,
@@ -895,7 +919,8 @@ var commandHandlers = [
895
919
  handleModelCommand,
896
920
  handleCompactCommand,
897
921
  handleReloadCommand,
898
- handleResetSessionCommand
922
+ handleResetSessionCommand,
923
+ handleReactionCommand
899
924
  ];
900
925
  async function executeSessionCommand(input, context) {
901
926
  const trimmedInput = input.trim();
@@ -1150,17 +1175,17 @@ function chunkByLines(text, maxSize) {
1150
1175
  }
1151
1176
  return chunks;
1152
1177
  }
1153
- var WORKING_EMOJI = "⚙️";
1154
- async function addWorkingReaction(message) {
1178
+ var DEFAULT_WORKING_EMOJI = "⚙️";
1179
+ async function addWorkingReaction(message, emoji = DEFAULT_WORKING_EMOJI) {
1155
1180
  try {
1156
- await message.react(WORKING_EMOJI);
1181
+ await message.react(emoji);
1157
1182
  } catch (error) {
1158
1183
  logger7.debug({ messageId: message.id, error }, "failed to add working reaction");
1159
1184
  }
1160
1185
  }
1161
- async function removeWorkingReaction(message) {
1186
+ async function removeWorkingReaction(message, emoji = DEFAULT_WORKING_EMOJI) {
1162
1187
  try {
1163
- const reaction = message.reactions.cache.get(WORKING_EMOJI);
1188
+ const reaction = message.reactions.cache.get(emoji);
1164
1189
  if (reaction) {
1165
1190
  await reaction.users.remove(message.client.user);
1166
1191
  }
@@ -1523,11 +1548,9 @@ function buildDiscordPromptContent(message, scope, content, config) {
1523
1548
  }
1524
1549
  async function handleDiscordMessage(message, config, agentService, sessionRegistry, accessConfig) {
1525
1550
  if (message.author.bot) {
1526
- logger11.debug("ignored bot message");
1527
1551
  return;
1528
1552
  }
1529
1553
  if (message.system) {
1530
- logger11.debug({ messageId: message.id }, "ignored system message");
1531
1554
  return;
1532
1555
  }
1533
1556
  const scope = resolveMessageScope(message);
@@ -1563,11 +1586,7 @@ ${attachment.content}`;
1563
1586
  return;
1564
1587
  }
1565
1588
  logger11.info({
1566
- direction: "IN",
1567
1589
  scope,
1568
- messageId: message.id,
1569
- authorId: message.author.id,
1570
- channelType: message.channel.type,
1571
1590
  content
1572
1591
  }, "message received");
1573
1592
  const channelKey = message.channel.id;
@@ -1585,10 +1604,15 @@ ${attachment.content}`;
1585
1604
  const commandResult = await executeSessionCommand(content, {
1586
1605
  agentService,
1587
1606
  promptQueue,
1588
- session
1607
+ session,
1608
+ workingEmoji: entry.workingEmoji
1589
1609
  });
1590
1610
  if (commandResult.handled) {
1591
1611
  stopTypingForChannel(channelKey);
1612
+ if (commandResult.workingEmoji) {
1613
+ entry.workingEmoji = commandResult.workingEmoji;
1614
+ logger11.info({ scope, emoji: commandResult.workingEmoji }, "working emoji updated");
1615
+ }
1592
1616
  if (commandResult.archive && scope.startsWith("thread:")) {
1593
1617
  logger11.info({ scope }, "archiving thread");
1594
1618
  const archiveChannel = message.channel;
@@ -1622,7 +1646,7 @@ ${commandResult.response ?? "Archiving..."}
1622
1646
  logger11.debug({ messageId: message.id }, "channel not sendable");
1623
1647
  return;
1624
1648
  }
1625
- await addWorkingReaction(message);
1649
+ await addWorkingReaction(message, entry.workingEmoji);
1626
1650
  const queuePosition = promptQueue.getSnapshot().pending;
1627
1651
  if (queuePosition > 0) {
1628
1652
  await sendReply(message, `Queued. ${queuePosition} request(s) ahead of this one.`);
@@ -1647,7 +1671,7 @@ ${commandResult.response ?? "Archiving..."}
1647
1671
  });
1648
1672
  } finally {
1649
1673
  stopTypingForChannel(channelKey);
1650
- await removeWorkingReaction(message);
1674
+ await removeWorkingReaction(message, entry.workingEmoji);
1651
1675
  }
1652
1676
  await sendReply(message, response);
1653
1677
  }
@@ -1768,7 +1792,8 @@ class SessionRegistry {
1768
1792
  const entry = {
1769
1793
  session,
1770
1794
  promptQueue,
1771
- createdAt: new Date
1795
+ createdAt: new Date,
1796
+ workingEmoji: DEFAULT_WORKING_EMOJI
1772
1797
  };
1773
1798
  this.scopes.set(scope, entry);
1774
1799
  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.17",
4
4
  "description": "Reusable Discord gateway for persistent pi agent sessions",
5
5
  "license": "MIT",
6
6
  "type": "module",