@llblab/pi-kit 0.1.6 → 0.1.7
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 +4 -0
- package/README.md +1 -1
- package/node_modules/@llblab/pi-telegram/CHANGELOG.md +4 -0
- package/node_modules/@llblab/pi-telegram/docs/architecture.md +2 -2
- package/node_modules/@llblab/pi-telegram/lib/bindings.ts +11 -0
- package/node_modules/@llblab/pi-telegram/lib/queue.ts +14 -0
- package/node_modules/@llblab/pi-telegram/package.json +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@llblab/pi-kit` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.1.7 - 2026-08-22
|
|
6
|
+
|
|
7
|
+
- `Telegram Hotfix`: Advances `@llblab/pi-telegram` to `0.36.11`, bringing at-most-once durable prompt dispatch that prevents session or process replacement from automatically replaying an already-admitted Telegram prompt.
|
|
8
|
+
|
|
5
9
|
## 0.1.6 - 2026-08-22
|
|
6
10
|
|
|
7
11
|
- `Extension Releases`: Advances `@llblab/pi-actors` to `0.50.0` and `@llblab/pi-telegram` to `0.36.10`, bringing their latest released runtime, Skill, and Telegram integration updates into the bundled kit.
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| `@llblab/pi-actors` | `0.50.0` | Extension and Skills |
|
|
10
10
|
| `@llblab/pi-codex-usage` | `0.9.3` | Extension |
|
|
11
11
|
| `@llblab/pi-grow-loop` | `0.7.2` | Extension and Skills |
|
|
12
|
-
| `@llblab/pi-telegram` | `0.36.
|
|
12
|
+
| `@llblab/pi-telegram` | `0.36.11` | Extension and Skills |
|
|
13
13
|
|
|
14
14
|
Versions are exact by design. Updating an extension does not change an installed kit until this repository explicitly advances that dependency and publishes a new kit version.
|
|
15
15
|
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
> Each release keeps at most 8 outcome records of at most 512 characters.
|
|
4
4
|
|
|
5
|
+
## 0.36.11: At-Most-Once Prompt Dispatch Hotfix
|
|
6
|
+
|
|
7
|
+
- `At-Most-Once Prompt Dispatch`: Commits each exact durable Telegram receipt synchronously before Pi model admission and blocks dispatch when that commit fails, closing the session/process-replacement replay window that could deliver an already-processed old prompt again; the narrow commit-before-admission crash boundary now favors no duplicate over retry.
|
|
8
|
+
|
|
5
9
|
## 0.36.10: Transport-Fenced Typing Hotfix
|
|
6
10
|
|
|
7
11
|
- `Typing Authority Fence`: Starts and continues Telegram typing activity only while the Pi instance has direct ownership or a live follower registration, stopping quietly when authority disappears so classic takeover cannot re-arm a stale loop or flood diagnostics with expected follower-registration errors.
|
|
@@ -198,7 +198,7 @@ All inbound updates are gated by the configured authorized user id.
|
|
|
198
198
|
5. Coalesce media groups, likely split long text, and one adjacent forward-plus-comment pair in either order when needed.
|
|
199
199
|
6. Download files with size limits and partial-download cleanup, then run configured/programmatic inbound handlers.
|
|
200
200
|
7. Build a prompt or control queue item carrying an exact durable receipt for every contributing update id.
|
|
201
|
-
8. Remove journal authority
|
|
201
|
+
8. Remove local prompt journal authority synchronously immediately before `sendUserMessage`, so session/process replacement can lose an unstarted prompt at that narrow crash boundary but can never replay a prompt already admitted to Pi; controls and foreign forwarding retain their explicit settlement boundaries.
|
|
202
202
|
9. Handle `edited_message` updates separately while the original turn is still queued and dispatch only when all safety gates are clear.
|
|
203
203
|
|
|
204
204
|
#### Durable Admission And Recovery
|
|
@@ -286,7 +286,7 @@ Dispatch requires:
|
|
|
286
286
|
|
|
287
287
|
A dispatched prompt remains queued until `agent_start` consumes it. This keeps the active Telegram turn bound for previews, attachments, aborts, and final replies. A low-level `agent_end` error also retains that active turn because Pi may retry automatically; a later successful `agent_end` delivers through the original target and metadata, while `agent_settled` proves that an unrecovered error can be finalized once before queue dispatch resumes.
|
|
288
288
|
|
|
289
|
-
Post-agent-end queue dispatch uses a session-bound deferred dispatcher. It is activated on session start, clears timers on shutdown, and skips callbacks from older generations before touching `ExtensionContext`. Dispatch stays session-bound after polling ownership moves elsewhere. When a queued Telegram prompt is forwarded into Pi,
|
|
289
|
+
Post-agent-end queue dispatch uses a session-bound deferred dispatcher. It is activated on session start, clears timers on shutdown, and skips callbacks from older generations before touching `ExtensionContext`. Dispatch stays session-bound after polling ownership moves elsewhere. When a queued Telegram prompt is forwarded into Pi, the bridge synchronously commits its exact durable receipt before calling normal `sendUserMessage(content)`; failed receipt commitment blocks dispatch, while the unavoidable crash window between commitment and Pi admission favors at-most-once execution over replay. It does not use Pi's `followUp` delivery option or inject terminal input.
|
|
290
290
|
|
|
291
291
|
One monotonic session generation also fences agent/tool/message events, compaction callbacks, preview state, scheduled final delivery, controls, and shutdown. Distinct Pi context objects observed within one session adopt that generation; contexts already observed under an older generation remain stale after replacement. Session start invalidates pending preview work, delayed finals check their captured context before delivery, and shutdown rechecks after asynchronous polling/preview boundaries with a bounded preview-clear wait.
|
|
292
292
|
|
|
@@ -68,6 +68,10 @@ export function createTelegramQueueBindingRuntime<TContext>(deps: {
|
|
|
68
68
|
ctx: TContext,
|
|
69
69
|
) => void;
|
|
70
70
|
isItemReady: (item: Queue.TelegramQueueItem<TContext>) => boolean;
|
|
71
|
+
onPromptHandedOff?: (
|
|
72
|
+
item: Queue.PendingTelegramTurn,
|
|
73
|
+
ctx: TContext,
|
|
74
|
+
) => void;
|
|
71
75
|
onControlSettled: (
|
|
72
76
|
item: Queue.PendingTelegramControlItem<TContext>,
|
|
73
77
|
ctx: TContext,
|
|
@@ -122,6 +126,13 @@ export function createTelegramQueueBindingRuntime<TContext>(deps: {
|
|
|
122
126
|
(item.admissionReceipts?.length ?? 0) === 0
|
|
123
127
|
);
|
|
124
128
|
},
|
|
129
|
+
commitPromptDispatch(item, ctx) {
|
|
130
|
+
if ((item.admissionReceipts?.length ?? 0) === 0) return true;
|
|
131
|
+
const settlement = deps.admission.getSettlement();
|
|
132
|
+
if (!settlement?.onPromptHandedOff) return false;
|
|
133
|
+
settlement.onPromptHandedOff(item, ctx);
|
|
134
|
+
return !settlement.isItemReady(item);
|
|
135
|
+
},
|
|
125
136
|
onControlSettled(item, ctx) {
|
|
126
137
|
deps.admission.getSettlement()?.onControlSettled(item, ctx);
|
|
127
138
|
},
|
|
@@ -2836,6 +2836,9 @@ export interface TelegramDispatchRuntimeDeps<TContext = unknown> {
|
|
|
2836
2836
|
>["item"],
|
|
2837
2837
|
) => void;
|
|
2838
2838
|
onPromptDispatchStart: (chatId: number) => void;
|
|
2839
|
+
commitPromptDispatch?: (
|
|
2840
|
+
item: Extract<TelegramQueueDispatchAction<TContext>, { kind: "prompt" }>["item"],
|
|
2841
|
+
) => boolean;
|
|
2839
2842
|
sendUserMessage: (
|
|
2840
2843
|
content: Extract<
|
|
2841
2844
|
TelegramQueueDispatchAction,
|
|
@@ -2859,6 +2862,10 @@ export interface TelegramQueueDispatchControllerDeps<
|
|
|
2859
2862
|
updateStatus: (ctx: TContext, error?: string) => void;
|
|
2860
2863
|
sendTextReply: TelegramControlRuntimeDeps<TContext>["sendTextReply"];
|
|
2861
2864
|
onPromptDispatchStart: (ctx: TContext, chatId: number) => void;
|
|
2865
|
+
commitPromptDispatch?: (
|
|
2866
|
+
item: Extract<TelegramQueueDispatchAction<TContext>, { kind: "prompt" }>["item"],
|
|
2867
|
+
ctx: TContext,
|
|
2868
|
+
) => boolean;
|
|
2862
2869
|
sendUserMessage: TelegramDispatchRuntimeDeps<TContext>["sendUserMessage"];
|
|
2863
2870
|
onPromptDispatchFailure: (ctx: TContext, message: string) => void;
|
|
2864
2871
|
isQueueItemTransportActive?: (item: TelegramQueueItem<TContext>) => boolean;
|
|
@@ -2890,6 +2897,9 @@ export function executeTelegramQueueDispatchPlan<TContext = unknown>(
|
|
|
2890
2897
|
}
|
|
2891
2898
|
deps.onPromptDispatchStart(plan.item.chatId);
|
|
2892
2899
|
try {
|
|
2900
|
+
if (deps.commitPromptDispatch && !deps.commitPromptDispatch(plan.item)) {
|
|
2901
|
+
throw new Error("Telegram prompt dispatch could not be committed durably.");
|
|
2902
|
+
}
|
|
2893
2903
|
deps.sendUserMessage(plan.item.content);
|
|
2894
2904
|
} catch (error) {
|
|
2895
2905
|
const message = getTelegramQueueErrorMessage(error);
|
|
@@ -2922,6 +2932,7 @@ export function createTelegramQueueDispatchRuntime<TContext = unknown>(
|
|
|
2922
2932
|
updateStatus: deps.updateStatus,
|
|
2923
2933
|
sendTextReply: deps.sendTextReply,
|
|
2924
2934
|
onPromptDispatchStart: deps.onPromptDispatchStart,
|
|
2935
|
+
commitPromptDispatch: deps.commitPromptDispatch,
|
|
2925
2936
|
sendUserMessage: deps.sendUserMessage,
|
|
2926
2937
|
onPromptDispatchFailure: deps.onPromptDispatchFailure,
|
|
2927
2938
|
isQueueItemTransportActive: deps.isQueueItemTransportActive,
|
|
@@ -3061,6 +3072,9 @@ export function createTelegramQueueDispatchController<TContext = unknown>(
|
|
|
3061
3072
|
onPromptDispatchStart: (chatId) => {
|
|
3062
3073
|
deps.onPromptDispatchStart(ctx, chatId);
|
|
3063
3074
|
},
|
|
3075
|
+
commitPromptDispatch: deps.commitPromptDispatch
|
|
3076
|
+
? (item) => deps.commitPromptDispatch!(item, ctx)
|
|
3077
|
+
: undefined,
|
|
3064
3078
|
sendUserMessage: deps.sendUserMessage,
|
|
3065
3079
|
onPromptDispatchFailure: (message) => {
|
|
3066
3080
|
deps.onPromptDispatchFailure(ctx, message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llblab/pi-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@llblab/pi-actors": "0.50.0",
|
|
44
44
|
"@llblab/pi-codex-usage": "0.9.3",
|
|
45
45
|
"@llblab/pi-grow-loop": "0.7.2",
|
|
46
|
-
"@llblab/pi-telegram": "0.36.
|
|
46
|
+
"@llblab/pi-telegram": "0.36.11"
|
|
47
47
|
},
|
|
48
48
|
"bundledDependencies": [
|
|
49
49
|
"@llblab/pi-actors",
|