@llblab/pi-telegram 0.26.13 → 0.26.15

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/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.26.15: Follower Bus Timeout Hotfix
4
+
5
+ - `Follower Bus Timeout`: Restored the 30-second default for follower-client bus calls (update forwarding, thread-target control, and API calls) after an entrypoint compression pass dropped the explicit timeout and left the forwarding path falling through to the 1-second transport default. The shared default now lives on the follower client runtime as `TELEGRAM_BUS_FOLLOWER_CLIENT_TIMEOUT_MS`. Impact: leader-to-follower update forwarding no longer times out under load, so polling stops re-fetching and re-downloading the same update (which previously delivered one voice message as three identical turns).
6
+
7
+ ## 0.26.14: Reasoning Activity Throttle
8
+
9
+ - `Reasoning Throttle`: Added a minimum interval between reasoning-block edits (`TELEGRAM_REASONING_MIN_INTERVAL_MS = 1_200`) so the first frame publishes immediately while later frames wait until both the interval and the 160-char delta threshold pass. The final `reasoning-end`/`agent-end` flush stays unconditional, and the 24-frame cap is unchanged. Impact: fast-token models with very large reasoning blocks no longer push an edit per character burst, so parallel threads stop saturating the bus and inbound Telegram messages arrive without multi-second delay.
10
+
3
11
  ## 0.26.13: Entrypoint Compression And BotFather Prerequisites
4
12
 
5
13
  - `Entrypoint Compression`: Moved low-level policy out of `index.ts` into owning domains: the deferred queue dispatch delay defaults in the queue domain, the delivery generation seed is built by the delivery domain, the `target-bindings` sync slice key and the default profile name resolve from their domains, and bus-runtime capability answers come from the thread capability state. Removed a redundant follower client timeout literal that duplicated the domain default. Impact: the composition root wires ports while constants, generations, and capability decisions stay with their owning domains.
@@ -24,6 +24,7 @@ export const TELEGRAM_ACTIVITY_MESSAGE_MAX_CHARS = 3_900;
24
24
  export const TELEGRAM_ACTIVITY_MESSAGE_MAX_TOOLS = 6;
25
25
  export const TELEGRAM_REASONING_MESSAGE_MAX_FRAMES = 24;
26
26
  export const TELEGRAM_REASONING_BUFFER_MAX_CHARS = 1_200;
27
+ export const TELEGRAM_REASONING_MIN_INTERVAL_MS = 1_200;
27
28
  export const TELEGRAM_TOOL_UPDATE_MAX_ENTRIES = 4;
28
29
 
29
30
  interface ToolActivity {
@@ -291,6 +292,7 @@ export interface TelegramActivityVerbosityRuntime {
291
292
  export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
292
293
  getActivityMode: () => "quiet" | "thinking" | "tools" | "verbose";
293
294
  refreshActivityMode?: () => Promise<void>;
295
+ getNowMs?: () => number;
294
296
  resolveTarget: (event: TelegramActivityEvent) => TelegramTarget | undefined;
295
297
  captureAuthority: () => TAuthority;
296
298
  isAuthorityActive: (authority: TAuthority) => boolean;
@@ -315,6 +317,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
315
317
  let active = true;
316
318
  let generation = 0;
317
319
  let tail = Promise.resolve();
320
+ const getNowMs = deps.getNowMs ?? Date.now;
318
321
  let activityId: string | undefined;
319
322
  let authority: TAuthority | undefined;
320
323
  let target: TelegramTarget | undefined;
@@ -324,6 +327,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
324
327
  let lastReasoningMessageChars = 0;
325
328
  let reasoningMessage: ReasoningMessage | undefined;
326
329
  let reasoningBlocked = false;
330
+ let lastReasoningPublishMs = 0;
327
331
  let toolMessage: ToolMessage | undefined;
328
332
  const tools = new Map<string, ToolActivity>();
329
333
  const toolOrder: string[] = [];
@@ -338,6 +342,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
338
342
  lastReasoningMessageChars = 0;
339
343
  reasoningMessage = undefined;
340
344
  reasoningBlocked = false;
345
+ lastReasoningPublishMs = 0;
341
346
  toolMessage = undefined;
342
347
  tools.clear();
343
348
  toolOrder.length = 0;
@@ -412,6 +417,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
412
417
  if (generation !== acceptedGeneration) return;
413
418
  reasoningMessageFrames += 1;
414
419
  lastReasoningMessageChars = reasoningChars;
420
+ lastReasoningPublishMs = getNowMs();
415
421
  } catch (error) {
416
422
  deps.recordFailure?.(
417
423
  canEdit ? "reasoning-edit" : "reasoning-send",
@@ -552,10 +558,11 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
552
558
  reasoningBuffer = `${reasoningBuffer}${event.delta}`.slice(
553
559
  -TELEGRAM_REASONING_BUFFER_MAX_CHARS,
554
560
  );
555
- if (
556
- reasoningMessageFrames < TELEGRAM_REASONING_MESSAGE_MAX_FRAMES &&
561
+ if (reasoningMessageFrames < TELEGRAM_REASONING_MESSAGE_MAX_FRAMES &&
557
562
  (reasoningMessageFrames === 0 ||
558
- reasoningChars - lastReasoningMessageChars >= 160)
563
+ (getNowMs() - lastReasoningPublishMs >=
564
+ TELEGRAM_REASONING_MIN_INTERVAL_MS &&
565
+ reasoningChars - lastReasoningMessageChars >= 160))
559
566
  ) {
560
567
  await publishReasoning(event, acceptedGeneration);
561
568
  }
@@ -580,6 +587,7 @@ export function createTelegramActivityVerbosityRuntime<TAuthority>(deps: {
580
587
  reasoningChars = 0;
581
588
  reasoningMessageFrames = 0;
582
589
  lastReasoningMessageChars = 0;
590
+ lastReasoningPublishMs = 0;
583
591
  reasoningMessage = undefined;
584
592
  reasoningBlocked = false;
585
593
  return;
@@ -35,6 +35,7 @@ import {
35
35
 
36
36
  export const TELEGRAM_BUS_FOLLOWER_PROMOTION_GRACE_MS = 2_500;
37
37
  export const TELEGRAM_FOLLOWER_SESSION_HANDOFF_TTL_MS = 30_000;
38
+ export const TELEGRAM_BUS_FOLLOWER_CLIENT_TIMEOUT_MS = 30_000;
38
39
  export const TELEGRAM_BUS_FOLLOWER_REGISTRATION_RETRY_ATTEMPTS =
39
40
  TELEGRAM_BUS_REGISTRATION_RETRY.attempts;
40
41
  export const TELEGRAM_BUS_FOLLOWER_REGISTRATION_RETRY_DELAY_MS =
@@ -720,10 +721,12 @@ export function createTelegramBusFollowerClientRuntime<
720
721
  TMessage = unknown,
721
722
  >(deps: TelegramBusFollowerClientRuntimeDeps<TMessage>) {
722
723
  const createRequestId = createTelegramBusRequestIdFactory(deps.instanceId);
724
+ const timeoutMs =
725
+ deps.timeoutMs ?? TELEGRAM_BUS_FOLLOWER_CLIENT_TIMEOUT_MS;
723
726
  const sharedClientDeps = {
724
727
  socketPath: deps.socketPath,
725
728
  createRequestId,
726
- timeoutMs: deps.timeoutMs,
729
+ timeoutMs,
727
730
  };
728
731
  return {
729
732
  createRequestId,
@@ -756,7 +759,8 @@ export function createTelegramBusFollowerApiCaller(
756
759
  deps: TelegramBusFollowerApiCallerDeps,
757
760
  ): (method: string, args: unknown[]) => Promise<unknown> {
758
761
  const getNowMs = deps.getNowMs ?? Date.now;
759
- const timeoutMs = deps.timeoutMs ?? 30000;
762
+ const timeoutMs =
763
+ deps.timeoutMs ?? TELEGRAM_BUS_FOLLOWER_CLIENT_TIMEOUT_MS;
760
764
  return async (method, args) => {
761
765
  const socketPath = resolveTelegramBusSocketPath(deps.socketPath);
762
766
  let response: TelegramBusEnvelope | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.26.13",
3
+ "version": "0.26.15",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"