@friendlyrobot/discord-pi-agent 0.15.0 → 0.16.1

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.
package/README.md CHANGED
@@ -132,7 +132,6 @@ Pretty console logs use:
132
132
 
133
133
  - `discordAllowedForumChannelIds` — string array of forum channel IDs to respond in
134
134
  - `discordAllowedUserIds` — string array of allowed user IDs (defaults to `[discordAllowedUserId]`)
135
- - `sessionIdleTimeoutMs` — auto-shutdown idle thread sessions (null = never)
136
135
 
137
136
  ## Env helpers
138
137
 
@@ -149,7 +148,6 @@ Pretty console logs use:
149
148
  - `DISCORD_STARTUP_MESSAGE`
150
149
  - `DISCORD_FORUM_CHANNEL_IDS` — comma-separated forum channel IDs
151
150
  - `DISCORD_ALLOWED_USER_IDS` — comma-separated allowed user IDs
152
- - `DISCORD_SESSION_IDLE_TIMEOUT_MS` — idle timeout in ms
153
151
 
154
152
  If `PI_AGENT_CWD` is missing it falls back to `process.cwd()`.
155
153
  Set `DISCORD_STARTUP_MESSAGE=false` to disable the startup DM.
@@ -33,7 +33,6 @@ export declare class AgentService {
33
33
  private ensureConfiguredModel;
34
34
  private ensureModelForSession;
35
35
  private requireSession;
36
- private applyConfiguredThinkingLevel;
37
36
  private applyConfiguredThinkingLevelForSession;
38
37
  listModels(session?: AgentSession | null): Promise<string>;
39
38
  switchModel(provider: string, modelId: string, session?: AgentSession | null): Promise<string>;
@@ -12,4 +12,4 @@ export type CommandContext = {
12
12
  promptQueue: PromptQueue;
13
13
  session?: AgentSession;
14
14
  };
15
- export declare function handleCommand(input: string, context: CommandContext): Promise<CommandResult>;
15
+ export declare function executeCommand(input: string, context: CommandContext): Promise<CommandResult>;
@@ -8,4 +8,4 @@ import type { AgentService } from "./agent-service";
8
8
  * Creates a temporary in-memory session, sends the media, extracts the
9
9
  * assistant's text reply, then disposes the session.
10
10
  */
11
- export declare function describeImage(agentService: AgentService, imageData: string, mimeType: string, userText: string, visionModel: Model<any>): Promise<string>;
11
+ export declare function describeMediaAttachment(agentService: AgentService, imageData: string, mimeType: string, userText: string, visionModel: Model<any>): Promise<string>;
package/dist/index.js CHANGED
@@ -110,7 +110,7 @@ async function formatWithPrettier(text) {
110
110
 
111
111
  // src/reply-buffer.ts
112
112
  var logger3 = createModuleLogger("reply-buffer");
113
- async function collectReply(session, prompt, options = {}) {
113
+ async function runPromptAndCollectReply(session, prompt, options = {}) {
114
114
  let streamedText = "";
115
115
  let eventCount = 0;
116
116
  let toolCount = 0;
@@ -278,9 +278,7 @@ class AgentService {
278
278
  async prompt(text) {
279
279
  const session = this.requireSession();
280
280
  const transformedPrompt = await this.config.promptTransform(text);
281
- return collectReply(session, transformedPrompt, {
282
- logPrefix: `[agent:${session.sessionId}]`
283
- });
281
+ return runPromptAndCollectReply(session, transformedPrompt);
284
282
  }
285
283
  getSkillsSummary() {
286
284
  const result = this.resourceLoader.getSkills();
@@ -429,9 +427,6 @@ class AgentService {
429
427
  }
430
428
  return this.session;
431
429
  }
432
- async applyConfiguredThinkingLevel() {
433
- await this.applyConfiguredThinkingLevelForSession(this.requireSession());
434
- }
435
430
  async applyConfiguredThinkingLevelForSession(session) {
436
431
  if (session.supportsThinking()) {
437
432
  const available = session.getAvailableThinkingLevels();
@@ -547,8 +542,7 @@ function resolveConfig(config) {
547
542
  shutdownOnSignals: config.shutdownOnSignals ?? true,
548
543
  visionModelId: config.visionModelId?.trim() || null,
549
544
  discordAllowedForumChannelIds: config.discordAllowedForumChannelIds ?? [],
550
- discordAllowedUserIds: config.discordAllowedUserIds ?? [discordAllowedUserId],
551
- sessionIdleTimeoutMs: config.sessionIdleTimeoutMs ?? null
545
+ discordAllowedUserIds: config.discordAllowedUserIds ?? [discordAllowedUserId]
552
546
  };
553
547
  }
554
548
  function loadDiscordGatewayConfigFromEnv(overrides = {}) {
@@ -568,8 +562,7 @@ function loadDiscordGatewayConfigFromEnv(overrides = {}) {
568
562
  shutdownOnSignals: overrides.shutdownOnSignals,
569
563
  visionModelId: overrides.visionModelId ?? process.env.PI_VISION_MODEL_ID,
570
564
  discordAllowedForumChannelIds: overrides.discordAllowedForumChannelIds ?? parseStringArrayFromEnv("DISCORD_FORUM_CHANNEL_IDS") ?? [],
571
- discordAllowedUserIds: overrides.discordAllowedUserIds ?? parseStringArrayFromEnv("DISCORD_ALLOWED_USER_IDS"),
572
- sessionIdleTimeoutMs: overrides.sessionIdleTimeoutMs ?? parseOptionalIntFromEnv("DISCORD_SESSION_IDLE_TIMEOUT_MS") ?? undefined
565
+ discordAllowedUserIds: overrides.discordAllowedUserIds ?? parseStringArrayFromEnv("DISCORD_ALLOWED_USER_IDS")
573
566
  });
574
567
  }
575
568
  function readRequiredValue(name, value) {
@@ -618,14 +611,6 @@ function parseStringArrayFromEnv(key) {
618
611
  }
619
612
  return value.split(",").map((id) => id.trim()).filter(Boolean);
620
613
  }
621
- function parseOptionalIntFromEnv(key) {
622
- const value = process.env[key];
623
- if (!value) {
624
- return;
625
- }
626
- const parsed = parseInt(value, 10);
627
- return Number.isNaN(parsed) ? undefined : parsed;
628
- }
629
614
 
630
615
  // src/discord-gateway-client.ts
631
616
  import {
@@ -889,7 +874,7 @@ var commandHandlers = [
889
874
  handleReloadCommand,
890
875
  handleResetSessionCommand
891
876
  ];
892
- async function handleCommand(input, context) {
877
+ async function executeCommand(input, context) {
893
878
  const trimmedInput = input.trim();
894
879
  if (!trimmedInput.startsWith("!")) {
895
880
  return { handled: false };
@@ -1160,7 +1145,7 @@ async function sendReply(message, text) {
1160
1145
 
1161
1146
  // src/image-description.ts
1162
1147
  var logger7 = createModuleLogger("image-description");
1163
- async function describeImage(agentService, imageData, mimeType, userText, visionModel) {
1148
+ async function describeMediaAttachment(agentService, imageData, mimeType, userText, visionModel) {
1164
1149
  const session = await agentService.createTemporarySession();
1165
1150
  await session.setModel(visionModel);
1166
1151
  const mediaType = getMediaType(mimeType);
@@ -1307,7 +1292,7 @@ async function resolveMediaAttachmentsForPrompt(mediaAttachments, content, curre
1307
1292
  }, "describing media with vision model");
1308
1293
  const descriptions = [];
1309
1294
  for (const media of mediaAttachments) {
1310
- const description = await describeImage(agentService, media.data, media.mimeType, content, visionModel);
1295
+ const description = await describeMediaAttachment(agentService, media.data, media.mimeType, content, visionModel);
1311
1296
  const label = getMediaAttachmentLabel(media.filename, media.mimeType);
1312
1297
  descriptions.push(`${label}
1313
1298
  ${description}`);
@@ -1524,7 +1509,7 @@ ${attachment.content}`;
1524
1509
  threadName: message.channel.name
1525
1510
  }, "new thread session");
1526
1511
  }
1527
- const commandResult = await handleCommand(content, {
1512
+ const commandResult = await executeCommand(content, {
1528
1513
  agentService,
1529
1514
  promptQueue,
1530
1515
  session
@@ -1581,8 +1566,7 @@ ${attachment.content}`;
1581
1566
  }
1582
1567
  const wrappedContent = buildDiscordPromptContent(message, scope, promptContent, config);
1583
1568
  const transformedPrompt = await config.promptTransform(wrappedContent);
1584
- return collectReply(session, transformedPrompt, {
1585
- logPrefix: `[agent:${session.sessionId}]`,
1569
+ return runPromptAndCollectReply(session, transformedPrompt, {
1586
1570
  images: promptImages
1587
1571
  });
1588
1572
  });
@@ -1654,7 +1638,7 @@ class PromptQueue {
1654
1638
  reject(error);
1655
1639
  }
1656
1640
  });
1657
- this.kick();
1641
+ this.runNextTask();
1658
1642
  });
1659
1643
  }
1660
1644
  getSnapshot() {
@@ -1663,7 +1647,7 @@ class PromptQueue {
1663
1647
  busy: this.running
1664
1648
  };
1665
1649
  }
1666
- kick() {
1650
+ runNextTask() {
1667
1651
  if (this.running) {
1668
1652
  return;
1669
1653
  }
@@ -1674,7 +1658,7 @@ class PromptQueue {
1674
1658
  this.running = true;
1675
1659
  next().finally(() => {
1676
1660
  this.running = false;
1677
- this.kick();
1661
+ this.runNextTask();
1678
1662
  });
1679
1663
  }
1680
1664
  }
@@ -8,6 +8,6 @@ export declare class PromptQueue {
8
8
  private running;
9
9
  enqueue<T>(task: QueueTask<T>): Promise<T>;
10
10
  getSnapshot(): QueueSnapshot;
11
- private kick;
11
+ private runNextTask;
12
12
  }
13
13
  export {};
@@ -1,8 +1,7 @@
1
1
  import type { AgentSession } from "@earendil-works/pi-coding-agent";
2
2
  import type { ImageContent } from "@earendil-works/pi-ai";
3
3
  type CollectReplyOptions = {
4
- logPrefix?: string;
5
4
  images?: ImageContent[];
6
5
  };
7
- export declare function collectReply(session: AgentSession, prompt: string, options?: CollectReplyOptions): Promise<string>;
6
+ export declare function runPromptAndCollectReply(session: AgentSession, prompt: string, options?: CollectReplyOptions): Promise<string>;
8
7
  export {};
package/dist/types.d.ts CHANGED
@@ -25,8 +25,6 @@ export type DiscordGatewayConfig = {
25
25
  discordAllowedForumChannelIds?: string[];
26
26
  /** Which users can interact in forum threads (defaults to [discordAllowedUserId]). */
27
27
  discordAllowedUserIds?: string[];
28
- /** Auto-shutdown idle thread sessions after this many ms. */
29
- sessionIdleTimeoutMs?: number;
30
28
  };
31
29
  export type ResolvedDiscordGatewayConfig = {
32
30
  discordBotToken: string;
@@ -45,7 +43,6 @@ export type ResolvedDiscordGatewayConfig = {
45
43
  visionModelId: string | null;
46
44
  discordAllowedForumChannelIds: string[];
47
45
  discordAllowedUserIds: string[];
48
- sessionIdleTimeoutMs: number | null;
49
46
  };
50
47
  export type ContextUsageStatus = {
51
48
  tokens: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@friendlyrobot/discord-pi-agent",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "Reusable Discord gateway for persistent pi agent sessions",
5
5
  "license": "MIT",
6
6
  "type": "module",