@llblab/pi-telegram 0.27.8 → 0.27.10

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.27.10: Leader Thread Rebind Hotfix
4
+
5
+ - `Live Leader Target`: Reclaiming or replacing the current leader thread now updates the process-local leader identity immediately after the durable binding commits. Impact: live thread-name resolution no longer returns the deleted previous leader target, so another instance can address the rebound leader without receiving `message thread not found`.
6
+ - `Rebind Coverage`: The explicit new-slot reroute regression now requires the durable record, live leader target, slot, and thread name to converge before old-thread cleanup. Impact: future Thread reconciler changes cannot update persisted state while leaving agent-message routing on a stale target.
7
+
8
+ ## 0.27.9: Symmetric Agent-Turn Metadata Hotfix
9
+
10
+ - `Agent-Turn Prompt Shape`: Cross-instance turns now fold trusted source-thread attribution into the canonical Telegram prefix as `[telegram|thread:<destination>|from-thread:<source>] <message>` instead of emitting a separate `[agent|from-thread:<source>]` block. Impact: inter-thread prompts match the existing compact metadata grammar without allowing ordinary Telegram text to impersonate transport attribution.
11
+ - `Transport Preservation`: Source-thread metadata travels as an internal serialized message field so leader-to-follower bus forwarding preserves it across the local IPC boundary. Focused regressions prove synthetic construction and final prompt formatting.
12
+
3
13
  ## 0.27.8: Bidirectional Thread Routing Hotfix
4
14
 
5
15
  - `Directional Ownership`: Internal cross-instance turns now bypass only ownership of the already-sent Telegram message id while preserving ownership of the destination thread. Impact: follower-to-leader turns avoid bouncing back to their sender, while leader-to-follower and follower-to-follower turns still forward through the destination follower's live registration.
@@ -281,7 +281,7 @@ Follower instances receive normalized events, not raw Telegram transport interna
281
281
 
282
282
  Followers do not call Telegram Bot API directly for routed Telegram work. Instead, they call a leader-owned transport port:
283
283
 
284
- Explicit `telegram_message(..., thread)` delivery also uses the bus as an agent-message plane. The leader resolves the case-insensitive name or numeric id against live leader/follower registrations, rejects ambiguous, stale, same-instance, cross-chat, and replayed requests, then coordinates visible Bot API delivery with one source-attributed synthetic turn routed through the destination instance's ordinary queue. The destination sees `[agent|from-thread:<name>]`, not an impersonated user message. Generation fencing and request-ledger deduplication apply to both resolution and routing.
284
+ Explicit `telegram_message(..., thread)` delivery also uses the bus as an agent-message plane. The leader resolves the case-insensitive name or numeric id against live leader/follower registrations, rejects ambiguous, stale, same-instance, cross-chat, and replayed requests, then coordinates visible Bot API delivery with one source-attributed synthetic turn routed through the destination instance's ordinary queue. The destination sees `[telegram|thread:<destination>|from-thread:<source>]`, not an impersonated user message. Generation fencing and request-ledger deduplication apply to both resolution and routing.
285
285
 
286
286
  ```text
287
287
  follower reply/preview/upload/chat-action/download/callback-answer -> leader IPC -> Telegram API
package/index.ts CHANGED
@@ -729,6 +729,7 @@ export default function (pi: Pi.ExtensionAPI) {
729
729
  recordMessageOwnership: messageOwnershipRuntime.recordRouted,
730
730
  ...inboundBusProjectionRuntime,
731
731
  getCurrentLeaderEpoch,
732
+ setCurrentLeaderIdentity: telegramBusLeaderState.set,
732
733
  getThreadReconciliationMachineState: threadReconciliationRuntime.getState,
733
734
  recordThreadReconciliationPlan,
734
735
  handleTelegramTopicLifecycleUpdate: topicLifecycleSync,
@@ -109,7 +109,8 @@ export function createTelegramAgentMessageRuntime<TContext, TUpdate>(
109
109
  chat: { id: target.chatId, type: "private" as const },
110
110
  from: { id: allowedChatId, is_bot: false, first_name: "Pi Agent" },
111
111
  message_thread_id: target.threadId,
112
- text: `[agent|from-thread:${sourceLabel}]\n\n${input.message.text}`,
112
+ pi_telegram_agent_source_thread: sourceLabel,
113
+ text: input.message.text,
113
114
  } as TelegramRoutedMessage;
114
115
  await deps.handleUpdate(
115
116
  { message, [TELEGRAM_INTERNAL_AGENT_MESSAGE]: true } as TUpdate,
package/lib/routing.ts CHANGED
@@ -523,6 +523,11 @@ export interface TelegramInboundRouteRuntimeDeps<
523
523
  target: Queue.TelegramQueueTarget,
524
524
  ) => string | undefined;
525
525
  getCurrentLeaderEpoch?: () => number | string | undefined;
526
+ setCurrentLeaderIdentity?: (identity: {
527
+ target: Queue.TelegramQueueTarget;
528
+ slot?: string;
529
+ threadName?: string;
530
+ }) => void;
526
531
  getThreadReconciliationMachineState?: () =>
527
532
  ThreadReconciler.ThreadReconciliationMachineState | undefined;
528
533
  recordThreadReconciliationPlan?: (
@@ -1359,6 +1364,11 @@ export function createTelegramInboundRouteRuntime<
1359
1364
  rerouteConfirmedAtMs: nowMs,
1360
1365
  });
1361
1366
  await deps.threadStore.persist();
1367
+ deps.setCurrentLeaderIdentity?.({
1368
+ target: sourceTarget,
1369
+ slot,
1370
+ threadName,
1371
+ });
1362
1372
  if (deps.callApi) {
1363
1373
  try {
1364
1374
  await deps.callApi("editForumTopic", {
@@ -2340,6 +2350,11 @@ export function createTelegramInboundRouteRuntime<
2340
2350
  slot,
2341
2351
  });
2342
2352
  await deps.threadStore.persist();
2353
+ deps.setCurrentLeaderIdentity?.({
2354
+ target: { chatId: target.chatId, threadId: target.threadId },
2355
+ slot,
2356
+ threadName,
2357
+ });
2343
2358
  deps.recordRuntimeEvent?.(
2344
2359
  "bus",
2345
2360
  "Bus leader reclaimed unbound thread",
@@ -2449,6 +2464,11 @@ export function createTelegramInboundRouteRuntime<
2449
2464
  slot,
2450
2465
  });
2451
2466
  await deps.threadStore.persist();
2467
+ deps.setCurrentLeaderIdentity?.({
2468
+ target: { chatId: target.chatId, threadId: target.threadId },
2469
+ slot,
2470
+ threadName,
2471
+ });
2452
2472
  deps.recordRuntimeEvent?.(
2453
2473
  "bus",
2454
2474
  "Bus leader reclaimed stale-current unbound thread",
@@ -2515,6 +2535,11 @@ export function createTelegramInboundRouteRuntime<
2515
2535
  slot,
2516
2536
  });
2517
2537
  await deps.threadStore.persist();
2538
+ deps.setCurrentLeaderIdentity?.({
2539
+ target: { chatId: target.chatId, threadId: target.threadId },
2540
+ slot,
2541
+ threadName,
2542
+ });
2518
2543
  deps.recordRuntimeEvent?.(
2519
2544
  "bus",
2520
2545
  "Bus leader reclaimed unbound thread",
package/lib/turns.ts CHANGED
@@ -54,6 +54,7 @@ export interface TelegramTurnTarget {
54
54
  export interface TelegramTurnMessage {
55
55
  message_id: number;
56
56
  message_thread_id?: number;
57
+ pi_telegram_agent_source_thread?: string;
57
58
  chat: { id: number; type?: string };
58
59
  }
59
60
 
@@ -552,7 +553,10 @@ export function createTelegramPromptTurnRuntimeBuilder<
552
553
  const threadLabel = firstMessage
553
554
  ? deps.getTelegramThreadLabel?.(firstMessage)
554
555
  : undefined;
555
- const telegramPrefix = createTelegramTurnPrefix({ thread: threadLabel });
556
+ const telegramPrefix = createTelegramTurnPrefix({
557
+ thread: threadLabel,
558
+ "from-thread": firstMessage?.pi_telegram_agent_source_thread,
559
+ });
556
560
  return buildTelegramPromptTurnRuntime({
557
561
  telegramPrefix,
558
562
  messages,
package/lib/updates.ts CHANGED
@@ -129,6 +129,7 @@ export interface TelegramUpdateMessage {
129
129
  from?: TelegramUser;
130
130
  message_id?: number;
131
131
  message_thread_id?: number;
132
+ pi_telegram_agent_source_thread?: string;
132
133
  forum_topic_created?: unknown;
133
134
  forum_topic_closed?: unknown;
134
135
  forum_topic_reopened?: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llblab/pi-telegram",
3
- "version": "0.27.8",
3
+ "version": "0.27.10",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"