@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 +10 -0
- package/docs/multi-instance-bus.md +1 -1
- package/index.ts +1 -0
- package/lib/agent-messages.ts +2 -1
- package/lib/routing.ts +25 -0
- package/lib/turns.ts +5 -1
- package/lib/updates.ts +1 -0
- package/package.json +1 -1
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 `[
|
|
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,
|
package/lib/agent-messages.ts
CHANGED
|
@@ -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
|
-
|
|
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({
|
|
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;
|