@friendlyrobot/discord-pi-agent 0.5.3 → 0.5.5

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.
@@ -8,4 +8,8 @@ export type GatewayAuthConfig = {
8
8
  discordAllowedUserIds: string[];
9
9
  startupMessage: string | false;
10
10
  };
11
+ /**
12
+ * Combine a forum thread title with the post body for the initial session prompt.
13
+ */
14
+ export declare function buildThreadOpeningPrompt(threadName: string, content: string): string;
11
15
  export declare function startGatewayClient(config: ResolvedDiscordPiBridgeConfig, agentService: AgentService, sessionRegistry: SessionRegistry, authConfig: GatewayAuthConfig): Promise<Client>;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.js CHANGED
@@ -721,6 +721,11 @@ function chunkMessage(text, maxChunkSize = SAFE_MESSAGE_LIMIT) {
721
721
  }
722
722
 
723
723
  // src/discord-gateway-client.ts
724
+ function buildThreadOpeningPrompt(threadName, content) {
725
+ return `<thread_title>${threadName}</thread_title>
726
+
727
+ ${content}`;
728
+ }
724
729
  function resolveScope(message) {
725
730
  if (message.channel.type === ChannelType.DM) {
726
731
  return "dm";
@@ -777,9 +782,16 @@ async function sendReply(message, text) {
777
782
  if (!firstChunk) {
778
783
  return;
779
784
  }
780
- await message.reply(firstChunk);
781
- for (const chunk of remainingChunks) {
782
- await channel.send(chunk);
785
+ try {
786
+ await message.reply(firstChunk);
787
+ for (const chunk of remainingChunks) {
788
+ await channel.send(chunk);
789
+ }
790
+ } catch (error) {
791
+ console.error("[gateway] send reply failed", {
792
+ messageId: message.id,
793
+ error
794
+ });
783
795
  }
784
796
  }
785
797
  async function startGatewayClient(config, agentService, sessionRegistry, authConfig) {
@@ -873,7 +885,19 @@ async function onMessage(message, config, agentService, sessionRegistry, authCon
873
885
  console.log("[gateway] ignored empty message", { messageId: message.id });
874
886
  return;
875
887
  }
876
- const { session, promptQueue } = await sessionRegistry.getOrCreate(scope);
888
+ const { entry, created } = await sessionRegistry.getOrCreate(scope);
889
+ const { session, promptQueue } = entry;
890
+ let effectiveContent = content;
891
+ if (created && scope.startsWith("thread:")) {
892
+ const thread = message.channel;
893
+ if (thread.isThread() && thread.name) {
894
+ effectiveContent = buildThreadOpeningPrompt(thread.name, content);
895
+ console.log("[gateway] new thread session — prepending title", {
896
+ scope,
897
+ threadName: thread.name
898
+ });
899
+ }
900
+ }
877
901
  let typingInterval = null;
878
902
  if (message.channel.isSendable()) {
879
903
  typingInterval = startTypingInterval(message.channel);
@@ -927,7 +951,7 @@ async function onMessage(message, config, agentService, sessionRegistry, authCon
927
951
  }
928
952
  const response = await promptQueue.enqueue(async () => {
929
953
  console.log(`[queue] processing message ${message.id} in scope ${scope}`);
930
- const transformedPrompt = await config.promptTransform(content);
954
+ const transformedPrompt = await config.promptTransform(effectiveContent);
931
955
  return collectReply(session, transformedPrompt, {
932
956
  logPrefix: `[agent:${session.sessionId}]`
933
957
  });
@@ -1004,7 +1028,7 @@ class SessionRegistry {
1004
1028
  async getOrCreate(scope) {
1005
1029
  const existing = this.scopes.get(scope);
1006
1030
  if (existing) {
1007
- return existing;
1031
+ return { entry: existing, created: false };
1008
1032
  }
1009
1033
  const sessionDir = sessionDirForScope(this.agentService.getAgentDir(), scope);
1010
1034
  const session = await this.agentService.createSession(sessionDir);
@@ -1020,7 +1044,7 @@ class SessionRegistry {
1020
1044
  sessionDir,
1021
1045
  sessionId: session.sessionId
1022
1046
  });
1023
- return entry;
1047
+ return { entry, created: true };
1024
1048
  }
1025
1049
  async remove(scope) {
1026
1050
  const entry = this.scopes.get(scope);
@@ -18,7 +18,10 @@ export declare class SessionRegistry {
18
18
  private readonly scopes;
19
19
  private readonly agentService;
20
20
  constructor(agentService: AgentService);
21
- getOrCreate(scope: SessionScope): Promise<ScopeEntry>;
21
+ getOrCreate(scope: SessionScope): Promise<{
22
+ entry: ScopeEntry;
23
+ created: boolean;
24
+ }>;
22
25
  remove(scope: SessionScope): Promise<void>;
23
26
  get(scope: SessionScope): ScopeEntry | undefined;
24
27
  getScopes(): SessionScope[];
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@friendlyrobot/discord-pi-agent",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "Reusable Discord gateway bridge for persistent pi agent sessions",
5
5
  "license": "MIT",
6
6
  "type": "module",