@llblab/pi-telegram 0.52.2 → 0.53.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/AGENTS.md +9 -7
- package/BACKLOG.md +1 -18
- package/CHANGELOG.md +15 -0
- package/README.md +7 -11
- package/api/commands.ts +3 -0
- package/dist/api/commands.d.ts +1 -1
- package/dist/lib/activity-verbosity.d.ts +1 -5
- package/dist/lib/activity-verbosity.js +15 -42
- package/dist/lib/activity.d.ts +9 -0
- package/dist/lib/activity.js +39 -10
- package/dist/lib/agent-messages.js +7 -3
- package/dist/lib/bindings.d.ts +43 -5
- package/dist/lib/bindings.js +163 -20
- package/dist/lib/bus-api.d.ts +12 -0
- package/dist/lib/bus-api.js +182 -79
- package/dist/lib/bus-follower.d.ts +111 -31
- package/dist/lib/bus-follower.js +1324 -359
- package/dist/lib/bus-leader.d.ts +41 -91
- package/dist/lib/bus-leader.js +969 -637
- package/dist/lib/bus-transport.js +16 -9
- package/dist/lib/bus.d.ts +215 -18
- package/dist/lib/bus.js +1048 -327
- package/dist/lib/channel-posts.d.ts +5 -0
- package/dist/lib/channel-posts.js +434 -261
- package/dist/lib/command-templates.d.ts +26 -5
- package/dist/lib/command-templates.js +92 -176
- package/dist/lib/commands.d.ts +168 -82
- package/dist/lib/commands.js +1409 -291
- package/dist/lib/config.d.ts +1 -8
- package/dist/lib/config.js +34 -76
- package/dist/lib/delivery.d.ts +2 -2
- package/dist/lib/delivery.js +16 -16
- package/dist/lib/extension.js +639 -171
- package/dist/lib/generative-app-worker.mjs +19 -7
- package/dist/lib/generative-apps.d.ts +0 -5
- package/dist/lib/generative-apps.js +61 -49
- package/dist/lib/inbound.d.ts +5 -0
- package/dist/lib/inbound.js +35 -59
- package/dist/lib/journal.d.ts +33 -3
- package/dist/lib/journal.js +2063 -782
- package/dist/lib/lifecycle.d.ts +2 -6
- package/dist/lib/lifecycle.js +75 -58
- package/dist/lib/locks.d.ts +29 -3
- package/dist/lib/locks.js +289 -108
- package/dist/lib/logging.js +50 -14
- package/dist/lib/media.d.ts +22 -1
- package/dist/lib/media.js +46 -28
- package/dist/lib/menu-model.d.ts +19 -5
- package/dist/lib/menu-model.js +53 -11
- package/dist/lib/menu-queue.d.ts +5 -4
- package/dist/lib/menu-queue.js +45 -63
- package/dist/lib/menu-settings.d.ts +5 -4
- package/dist/lib/menu-settings.js +114 -78
- package/dist/lib/menu-status.d.ts +1 -1
- package/dist/lib/menu-status.js +8 -25
- package/dist/lib/menu-thinking.d.ts +6 -1
- package/dist/lib/menu-thinking.js +14 -21
- package/dist/lib/menu.d.ts +8 -61
- package/dist/lib/menu.js +92 -164
- package/dist/lib/model.d.ts +1 -1
- package/dist/lib/model.js +2 -16
- package/dist/lib/outbound-attachments.d.ts +6 -27
- package/dist/lib/outbound-attachments.js +45 -38
- package/dist/lib/outbound-buttons.js +22 -16
- package/dist/lib/outbound-markup.d.ts +0 -2
- package/dist/lib/outbound-markup.js +51 -64
- package/dist/lib/outbound-voice.js +6 -3
- package/dist/lib/outbound.d.ts +6 -6
- package/dist/lib/outbound.js +65 -51
- package/dist/lib/ownership.js +6 -2
- package/dist/lib/paths.d.ts +5 -0
- package/dist/lib/paths.js +37 -21
- package/dist/lib/pi.d.ts +2 -0
- package/dist/lib/pi.js +8 -1
- package/dist/lib/polling.d.ts +21 -37
- package/dist/lib/polling.js +59 -50
- package/dist/lib/preview.js +39 -19
- package/dist/lib/process-identity.d.ts +24 -0
- package/dist/lib/process-identity.js +133 -0
- package/dist/lib/prompts.js +2 -7
- package/dist/lib/queue.d.ts +14 -16
- package/dist/lib/queue.js +252 -127
- package/dist/lib/recovery.d.ts +2 -83
- package/dist/lib/recovery.js +20 -274
- package/dist/lib/replies.d.ts +16 -24
- package/dist/lib/replies.js +99 -116
- package/dist/lib/routing.d.ts +120 -7
- package/dist/lib/routing.js +4667 -1152
- package/dist/lib/runtime.d.ts +1 -11
- package/dist/lib/sections.d.ts +4 -29
- package/dist/lib/sections.js +7 -20
- package/dist/lib/skills.js +4 -3
- package/dist/lib/status.js +86 -57
- package/dist/lib/sync.d.ts +1 -3
- package/dist/lib/sync.js +67 -43
- package/dist/lib/target.d.ts +4 -0
- package/dist/lib/target.js +18 -0
- package/dist/lib/telegram-api.d.ts +18 -13
- package/dist/lib/telegram-api.js +148 -53
- package/dist/lib/text-groups.js +4 -39
- package/dist/lib/thread-cleanup-manager.d.ts +6 -27
- package/dist/lib/thread-cleanup-manager.js +369 -186
- package/dist/lib/thread-display.d.ts +1 -2
- package/dist/lib/thread-display.js +58 -38
- package/dist/lib/thread-naming.d.ts +28 -8
- package/dist/lib/thread-naming.js +175 -66
- package/dist/lib/thread-reconciler.d.ts +42 -16
- package/dist/lib/thread-reconciler.js +90 -50
- package/dist/lib/threads.d.ts +82 -20
- package/dist/lib/threads.js +2247 -855
- package/dist/lib/time-injection.js +1 -2
- package/dist/lib/turns.js +1 -19
- package/dist/lib/updates.d.ts +169 -80
- package/dist/lib/updates.js +2418 -641
- package/dist/lib/voice.d.ts +7 -22
- package/dist/lib/voice.js +7 -22
- package/dist/lib/wire.js +1 -1
- package/dist/lib/workspace-admission.d.ts +3 -1
- package/dist/lib/workspace-admission.js +425 -211
- package/dist/lib/workspace-identity.js +8 -13
- package/dist/lib/workspace-retirement.d.ts +1 -1
- package/dist/lib/workspace-retirement.js +328 -140
- package/dist/lib/workspace-slots.js +8 -4
- package/dist/package.json +1 -1
- package/docs/architecture.md +31 -29
- package/docs/inbound.md +1 -1
- package/docs/multi-instance-bus.md +15 -3
- package/docs/outbound.md +1 -1
- package/docs/public-api.md +29 -1
- package/docs/ui-style.md +25 -8
- package/lib/activity-verbosity.ts +59 -82
- package/lib/activity.ts +146 -102
- package/lib/agent-messages.ts +12 -5
- package/lib/bindings.ts +389 -82
- package/lib/bus-api.ts +263 -102
- package/lib/bus-follower.ts +2440 -601
- package/lib/bus-leader.ts +2209 -1290
- package/lib/bus-transport.ts +46 -12
- package/lib/bus.ts +1673 -444
- package/lib/channel-posts.ts +848 -327
- package/lib/command-templates.ts +152 -265
- package/lib/commands.ts +2398 -555
- package/lib/config.ts +177 -170
- package/lib/delivery.ts +41 -29
- package/lib/extension.ts +1206 -433
- package/lib/generative-app-worker.mjs +19 -7
- package/lib/generative-apps.ts +324 -211
- package/lib/inbound.ts +95 -97
- package/lib/journal.ts +5311 -1763
- package/lib/keyboard.ts +1 -3
- package/lib/lifecycle.ts +128 -78
- package/lib/locks.ts +677 -203
- package/lib/logging.ts +147 -58
- package/lib/media.ts +82 -43
- package/lib/menu-model.ts +85 -18
- package/lib/menu-queue.ts +88 -129
- package/lib/menu-settings.ts +260 -155
- package/lib/menu-status.ts +20 -60
- package/lib/menu-thinking.ts +41 -56
- package/lib/menu.ts +112 -285
- package/lib/model.ts +8 -22
- package/lib/outbound-attachments.ts +156 -125
- package/lib/outbound-buttons.ts +76 -49
- package/lib/outbound-markup.ts +96 -94
- package/lib/outbound-voice.ts +33 -27
- package/lib/outbound.ts +128 -125
- package/lib/ownership.ts +19 -10
- package/lib/paths.ts +148 -49
- package/lib/pi.ts +35 -15
- package/lib/polling.ts +144 -147
- package/lib/preview.ts +93 -40
- package/lib/process-identity.ts +164 -0
- package/lib/prompts.ts +4 -11
- package/lib/queue.ts +516 -301
- package/lib/recovery.ts +50 -454
- package/lib/rendering.ts +1 -3
- package/lib/replies.ts +248 -209
- package/lib/routing.ts +8509 -2186
- package/lib/runtime.ts +1 -12
- package/lib/sections.ts +24 -89
- package/lib/setup.ts +1 -3
- package/lib/skills.ts +9 -4
- package/lib/status.ts +215 -110
- package/lib/sync.ts +448 -361
- package/lib/target.ts +22 -3
- package/lib/telegram-api.ts +302 -127
- package/lib/text-groups.ts +5 -39
- package/lib/thread-cleanup-manager.ts +833 -331
- package/lib/thread-display.ts +213 -97
- package/lib/thread-naming.ts +232 -87
- package/lib/thread-reconciler.ts +155 -72
- package/lib/threads.ts +5318 -1845
- package/lib/time-injection.ts +1 -4
- package/lib/turns.ts +15 -28
- package/lib/updates.ts +5184 -1612
- package/lib/voice.ts +7 -35
- package/lib/wire.ts +1 -1
- package/lib/workspace-admission.ts +996 -416
- package/lib/workspace-identity.ts +14 -17
- package/lib/workspace-retirement.ts +878 -376
- package/lib/workspace-slots.ts +22 -13
- package/package.json +1 -1
- package/scripts/check-downgrade.mjs +0 -472
- package/scripts/measure-workspace.mjs +0 -108
package/lib/bindings.ts
CHANGED
|
@@ -4,16 +4,21 @@
|
|
|
4
4
|
* Owns pi-facing tool, command, and lifecycle hook registration for the entrypoint
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import * as Activity from "./activity.ts";
|
|
8
7
|
import * as ActivityVerbosity from "./activity-verbosity.ts";
|
|
8
|
+
import * as Activity from "./activity.ts";
|
|
9
|
+
import * as BusApi from "./bus-api.ts";
|
|
10
|
+
import type { TelegramBusFollowerCommandOwner } from "./bus-follower.ts";
|
|
11
|
+
import type { TelegramBusLiveRebindWorkState } from "./bus.ts";
|
|
9
12
|
import * as ChannelPosts from "./channel-posts.ts";
|
|
10
13
|
import * as CommandTemplates from "./command-templates.ts";
|
|
11
14
|
import * as Commands from "./commands.ts";
|
|
12
15
|
import * as Config from "./config.ts";
|
|
13
16
|
import * as Delivery from "./delivery.ts";
|
|
17
|
+
import * as GenerativeApps from "./generative-apps.ts";
|
|
14
18
|
import * as Keyboard from "./keyboard.ts";
|
|
15
19
|
import * as Lifecycle from "./lifecycle.ts";
|
|
16
20
|
import * as Locks from "./locks.ts";
|
|
21
|
+
import * as Menu from "./menu.ts";
|
|
17
22
|
import * as Model from "./model.ts";
|
|
18
23
|
import * as OutboundAttachments from "./outbound-attachments.ts";
|
|
19
24
|
import * as OutboundHandlers from "./outbound.ts";
|
|
@@ -26,9 +31,159 @@ import * as Routing from "./routing.ts";
|
|
|
26
31
|
import * as Runtime from "./runtime.ts";
|
|
27
32
|
import * as Setup from "./setup.ts";
|
|
28
33
|
import * as Status from "./status.ts";
|
|
29
|
-
import * as TelegramApi from "./telegram-api.ts";
|
|
30
34
|
import type { TelegramTarget } from "./target.ts";
|
|
31
|
-
import * as
|
|
35
|
+
import * as TelegramApi from "./telegram-api.ts";
|
|
36
|
+
|
|
37
|
+
/** Compose any registered held command over captured recipient effects; no ordinary follower API fallback. */
|
|
38
|
+
export function createTelegramFollowerSelectedCommandBinding<
|
|
39
|
+
TContext,
|
|
40
|
+
TModel extends Model.MenuModel = Model.MenuModel,
|
|
41
|
+
>(deps: {
|
|
42
|
+
ctx: TContext;
|
|
43
|
+
operationId: string;
|
|
44
|
+
registrationGeneration: string;
|
|
45
|
+
name: string;
|
|
46
|
+
target: TelegramTarget & { threadId: number };
|
|
47
|
+
recipient: Pick<
|
|
48
|
+
TelegramBusFollowerCommandOwner<TContext>,
|
|
49
|
+
"isCurrent" | "assertRecipientCurrent"
|
|
50
|
+
>;
|
|
51
|
+
command: Pick<
|
|
52
|
+
ReturnType<
|
|
53
|
+
typeof Commands.createTelegramCommandHandlerTargetRuntime<
|
|
54
|
+
Commands.TelegramCommandRuntimeMessage,
|
|
55
|
+
TContext
|
|
56
|
+
>
|
|
57
|
+
>,
|
|
58
|
+
"prepareHeldCommand" | "canPrepareHeldCommand"
|
|
59
|
+
>;
|
|
60
|
+
menu?: Omit<
|
|
61
|
+
Menu.TelegramMenuActionRuntimeDeps<TContext, TModel>,
|
|
62
|
+
"sendTextReply" | "sendInteractiveMessage" | "editInteractiveMessage"
|
|
63
|
+
>;
|
|
64
|
+
deliver: Parameters<
|
|
65
|
+
typeof BusApi.createTelegramSelectedMenuTextApi
|
|
66
|
+
>[0]["deliver"];
|
|
67
|
+
recordOwnership: NonNullable<
|
|
68
|
+
Replies.TelegramRenderedMessageDeliveryRuntimeDeps<Menu.TelegramReplyMarkup>["recordOwnership"]
|
|
69
|
+
>;
|
|
70
|
+
}): TelegramBusFollowerCommandOwner<TContext> | undefined {
|
|
71
|
+
const {
|
|
72
|
+
ctx,
|
|
73
|
+
operationId,
|
|
74
|
+
registrationGeneration,
|
|
75
|
+
name,
|
|
76
|
+
recipient,
|
|
77
|
+
command,
|
|
78
|
+
deliver,
|
|
79
|
+
recordOwnership,
|
|
80
|
+
} = deps,
|
|
81
|
+
target = { ...deps.target };
|
|
82
|
+
const prepare = command.prepareHeldCommand,
|
|
83
|
+
canPrepare = command.canPrepareHeldCommand;
|
|
84
|
+
const isCurrent = recipient.isCurrent,
|
|
85
|
+
assertRecipientCurrent = recipient.assertRecipientCurrent,
|
|
86
|
+
menu = deps.menu,
|
|
87
|
+
menuPorts = menu && { ...menu };
|
|
88
|
+
if (
|
|
89
|
+
[
|
|
90
|
+
prepare,
|
|
91
|
+
canPrepare,
|
|
92
|
+
isCurrent,
|
|
93
|
+
assertRecipientCurrent,
|
|
94
|
+
deliver,
|
|
95
|
+
recordOwnership,
|
|
96
|
+
].some((port) => typeof port !== "function") ||
|
|
97
|
+
(menuPorts &&
|
|
98
|
+
[
|
|
99
|
+
menuPorts.getModelMenuState,
|
|
100
|
+
menuPorts.storeModelMenuState,
|
|
101
|
+
menuPorts.getActiveModel,
|
|
102
|
+
menuPorts.getThinkingLevel,
|
|
103
|
+
menuPorts.buildStatusHtml,
|
|
104
|
+
menuPorts.isIdle,
|
|
105
|
+
menuPorts.canOfferInFlightModelSwitch,
|
|
106
|
+
].some((port) => typeof port !== "function"))
|
|
107
|
+
)
|
|
108
|
+
return undefined;
|
|
109
|
+
const portsCurrent = () =>
|
|
110
|
+
deps.ctx === ctx &&
|
|
111
|
+
deps.operationId === operationId &&
|
|
112
|
+
deps.registrationGeneration === registrationGeneration &&
|
|
113
|
+
deps.name === name &&
|
|
114
|
+
deps.recipient === recipient &&
|
|
115
|
+
recipient.isCurrent === isCurrent &&
|
|
116
|
+
recipient.assertRecipientCurrent === assertRecipientCurrent &&
|
|
117
|
+
deps.command === command &&
|
|
118
|
+
command.prepareHeldCommand === prepare &&
|
|
119
|
+
command.canPrepareHeldCommand === canPrepare &&
|
|
120
|
+
deps.deliver === deliver &&
|
|
121
|
+
deps.recordOwnership === recordOwnership &&
|
|
122
|
+
deps.menu === menu &&
|
|
123
|
+
(!menuPorts ||
|
|
124
|
+
Object.entries(menuPorts).every(
|
|
125
|
+
([key, value]) => Reflect.get(menu!, key) === value,
|
|
126
|
+
));
|
|
127
|
+
const current = () =>
|
|
128
|
+
portsCurrent() && isCurrent.call(recipient) && portsCurrent();
|
|
129
|
+
if (!current()) return undefined;
|
|
130
|
+
const api = BusApi.createTelegramSelectedMenuTextApi({
|
|
131
|
+
operationId,
|
|
132
|
+
registrationGeneration,
|
|
133
|
+
target,
|
|
134
|
+
assertAuthority: assertRecipientCurrent,
|
|
135
|
+
deliver,
|
|
136
|
+
});
|
|
137
|
+
const rendered =
|
|
138
|
+
Replies.createTelegramRenderedMessageDeliveryRuntime<Menu.TelegramReplyMarkup>(
|
|
139
|
+
{
|
|
140
|
+
sendMessage: api.sendMessage,
|
|
141
|
+
editMessage: api.editMessageText,
|
|
142
|
+
recordOwnership,
|
|
143
|
+
async sendRichMessage() {
|
|
144
|
+
throw new Error(
|
|
145
|
+
"Selected command has no rich or ordinary API fallback.",
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
const menus =
|
|
151
|
+
menuPorts &&
|
|
152
|
+
Menu.createTelegramMenuActionRuntime({
|
|
153
|
+
...menuPorts,
|
|
154
|
+
sendTextReply: rendered.sendTextReply,
|
|
155
|
+
sendInteractiveMessage: rendered.sendInteractiveMessage,
|
|
156
|
+
editInteractiveMessage: rendered.editInteractiveMessage,
|
|
157
|
+
});
|
|
158
|
+
const effects = {
|
|
159
|
+
sendTextReply: rendered.sendTextReply,
|
|
160
|
+
...(menus ? { showStatus: menus.sendStatusMessage } : {}),
|
|
161
|
+
};
|
|
162
|
+
if (!canPrepare.call(command, name, effects) || !current()) return undefined;
|
|
163
|
+
return {
|
|
164
|
+
isCurrent: current,
|
|
165
|
+
assertRecipientCurrent,
|
|
166
|
+
prepare(readiness, context, input) {
|
|
167
|
+
if (
|
|
168
|
+
!current() ||
|
|
169
|
+
context !== ctx ||
|
|
170
|
+
input.target.chatId !== target.chatId ||
|
|
171
|
+
input.target.threadId !== target.threadId ||
|
|
172
|
+
input.assertRecipientCurrent !== assertRecipientCurrent
|
|
173
|
+
)
|
|
174
|
+
return undefined;
|
|
175
|
+
const plan = prepare.call(
|
|
176
|
+
command,
|
|
177
|
+
name,
|
|
178
|
+
readiness,
|
|
179
|
+
context,
|
|
180
|
+
input,
|
|
181
|
+
effects,
|
|
182
|
+
);
|
|
183
|
+
return current() ? plan : undefined;
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
32
187
|
|
|
33
188
|
type ActivePiModel = NonNullable<Pi.ExtensionContext["model"]>;
|
|
34
189
|
|
|
@@ -120,9 +275,7 @@ export function createTelegramQueueBindingRuntime<TContext>(deps: {
|
|
|
120
275
|
allocateLaneOrder: deps.queue.allocateItemOrder,
|
|
121
276
|
onItemsDiscarded(items, ctx) {
|
|
122
277
|
if (!settleDiscardedItems(items, ctx)) {
|
|
123
|
-
throw new Error(
|
|
124
|
-
"Telegram queue items could not be discarded durably.",
|
|
125
|
-
);
|
|
278
|
+
throw new Error("Telegram queue items could not be discarded durably.");
|
|
126
279
|
}
|
|
127
280
|
},
|
|
128
281
|
updateStatus: deps.updateStatus,
|
|
@@ -188,19 +341,21 @@ export interface TelegramGenerativeAppLiveSurfaceBinding {
|
|
|
188
341
|
| GenerativeApps.GenerativeAppLiveSurfaceRuntime<GenerativeApps.TelegramBindLiveHandle>
|
|
189
342
|
| undefined;
|
|
190
343
|
set: (
|
|
191
|
-
runtime:
|
|
344
|
+
runtime:
|
|
345
|
+
| GenerativeApps.GenerativeAppLiveSurfaceRuntime<GenerativeApps.TelegramBindLiveHandle>
|
|
192
346
|
| undefined,
|
|
193
347
|
) => void;
|
|
194
348
|
shutdown: () => void;
|
|
195
349
|
}
|
|
196
350
|
|
|
197
|
-
export function createTelegramGenerativeAppLiveSurfaceBinding():
|
|
198
|
-
TelegramGenerativeAppLiveSurfaceBinding {
|
|
351
|
+
export function createTelegramGenerativeAppLiveSurfaceBinding(): TelegramGenerativeAppLiveSurfaceBinding {
|
|
199
352
|
let current:
|
|
200
353
|
| GenerativeApps.GenerativeAppLiveSurfaceRuntime<GenerativeApps.TelegramBindLiveHandle>
|
|
201
354
|
| undefined;
|
|
202
355
|
return {
|
|
203
|
-
get() {
|
|
356
|
+
get() {
|
|
357
|
+
return current;
|
|
358
|
+
},
|
|
204
359
|
set(runtime) {
|
|
205
360
|
current?.shutdown();
|
|
206
361
|
current = runtime;
|
|
@@ -214,17 +369,25 @@ TelegramGenerativeAppLiveSurfaceBinding {
|
|
|
214
369
|
|
|
215
370
|
export function createTelegramGenerativeAppBoundButtonActionInvoker<
|
|
216
371
|
TQuery extends {
|
|
217
|
-
message?: {
|
|
372
|
+
message?: {
|
|
373
|
+
chat?: { id?: number };
|
|
374
|
+
message_id?: number;
|
|
375
|
+
message_thread_id?: number;
|
|
376
|
+
};
|
|
218
377
|
},
|
|
219
378
|
>(deps: {
|
|
220
379
|
agentDir: string;
|
|
221
380
|
assertExecutionCurrent: (query: TQuery) => void;
|
|
222
|
-
getExecutionFence: (
|
|
381
|
+
getExecutionFence: (
|
|
382
|
+
query: TQuery,
|
|
383
|
+
) => GenerativeApps.GenerativeAppExecutionFence | undefined;
|
|
223
384
|
getActiveProfileName?: () => string | undefined;
|
|
224
385
|
getLiveSurfaceRuntime?: () =>
|
|
225
386
|
| GenerativeApps.GenerativeAppLiveSurfaceRuntime<GenerativeApps.TelegramBindLiveHandle>
|
|
226
387
|
| undefined;
|
|
227
|
-
planOutput: ReturnType<
|
|
388
|
+
planOutput: ReturnType<
|
|
389
|
+
typeof OutboundHandlers.createTelegramOutboundReplyPlanner
|
|
390
|
+
>;
|
|
228
391
|
sendMarkdownReply: (
|
|
229
392
|
chatId: number,
|
|
230
393
|
replyToMessageId: number,
|
|
@@ -258,16 +421,18 @@ export function createTelegramGenerativeAppBoundButtonActionInvoker<
|
|
|
258
421
|
throw new Error("Generative App callback target is unavailable.");
|
|
259
422
|
}
|
|
260
423
|
const liveSurfaces = deps.getLiveSurfaceRuntime?.();
|
|
261
|
-
handedOff = liveSurfaces?.take(
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
424
|
+
handedOff = liveSurfaces?.take(
|
|
425
|
+
GenerativeApps.getTelegramBindLiveSurfaceKey(
|
|
426
|
+
boundAction.app,
|
|
427
|
+
deps.getActiveProfileName?.() ?? "default",
|
|
428
|
+
{
|
|
429
|
+
chatId,
|
|
430
|
+
...(query.message?.message_thread_id !== undefined
|
|
431
|
+
? { threadId: query.message.message_thread_id }
|
|
432
|
+
: {}),
|
|
433
|
+
},
|
|
434
|
+
),
|
|
435
|
+
);
|
|
271
436
|
const result = await GenerativeApps.invokeGenerativeApp({
|
|
272
437
|
agentDir: deps.agentDir,
|
|
273
438
|
...(deps.getExecutionFence(query)
|
|
@@ -424,7 +589,8 @@ export function createTelegramAssistantOutputBindingRuntime<
|
|
|
424
589
|
typeof OutboundHandlers.createTelegramAssistantOutputSender<TTransportStamp>
|
|
425
590
|
>[0];
|
|
426
591
|
waitForActivityIdle?: () => Promise<void>;
|
|
427
|
-
prepareTelegramPreview?: () =>
|
|
592
|
+
prepareTelegramPreview?: () =>
|
|
593
|
+
Activity.TelegramAssistantOutputPreparation | undefined;
|
|
428
594
|
enqueue?: Activity.TelegramActivityPublicationRuntime["enqueue"];
|
|
429
595
|
recordRuntimeEvent: TelegramRuntimeEventRecorder;
|
|
430
596
|
}): TelegramAssistantOutputBindingRuntime<TTransportStamp> {
|
|
@@ -438,7 +604,8 @@ export function createTelegramAssistantOutputBindingRuntime<
|
|
|
438
604
|
const runtime = Activity.createTelegramAssistantOutputRuntime({
|
|
439
605
|
...authority,
|
|
440
606
|
enqueue: deps.enqueue,
|
|
441
|
-
prepareSend: (event) =>
|
|
607
|
+
prepareSend: (event) =>
|
|
608
|
+
event.source === "telegram" ? deps.prepareTelegramPreview?.() : undefined,
|
|
442
609
|
async send(event, authority, isAuthorityActive) {
|
|
443
610
|
await deps.waitForActivityIdle?.();
|
|
444
611
|
if (!isAuthorityActive()) return;
|
|
@@ -468,7 +635,13 @@ type TelegramAssistantOutputAuthority<TTransportStamp> = ReturnType<
|
|
|
468
635
|
export interface TelegramBridgePublicationRuntime {
|
|
469
636
|
enqueue: Activity.TelegramActivityPublicationRuntime["enqueue"];
|
|
470
637
|
reserve: Activity.TelegramActivityPublicationRuntime["reserve"];
|
|
471
|
-
|
|
638
|
+
hasPending: Activity.TelegramActivityPublicationRuntime["hasPending"];
|
|
639
|
+
beginWork: Activity.TelegramActivityPublicationRuntime["beginWork"];
|
|
640
|
+
hasUnconfirmed: Activity.TelegramActivityPublicationRuntime["hasUnconfirmed"];
|
|
641
|
+
capture: () => {
|
|
642
|
+
target?: Queue.TelegramQueueTarget;
|
|
643
|
+
isCurrent: () => boolean;
|
|
644
|
+
};
|
|
472
645
|
}
|
|
473
646
|
|
|
474
647
|
export interface TelegramActivityBindingRuntime {
|
|
@@ -497,11 +670,10 @@ export function createTelegramActivityBindingRuntime<TTransportStamp>(deps: {
|
|
|
497
670
|
>;
|
|
498
671
|
}): TelegramActivityBindingRuntime {
|
|
499
672
|
const publication = Activity.createTelegramActivityPublicationRuntime();
|
|
500
|
-
const assistantOutputBinding =
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
});
|
|
673
|
+
const assistantOutputBinding = createTelegramAssistantOutputBindingRuntime({
|
|
674
|
+
...deps.assistantOutput,
|
|
675
|
+
enqueue: publication.enqueue,
|
|
676
|
+
});
|
|
505
677
|
const activityVerbosityRuntime =
|
|
506
678
|
ActivityVerbosity.createTelegramActivityVerbosityRuntime({
|
|
507
679
|
...deps.activityVerbosity,
|
|
@@ -547,17 +719,88 @@ export function createTelegramActivityBindingRuntime<TTransportStamp>(deps: {
|
|
|
547
719
|
publicationRuntime: {
|
|
548
720
|
enqueue: publication.enqueue,
|
|
549
721
|
reserve: publication.reserve,
|
|
722
|
+
hasPending: publication.hasPending,
|
|
723
|
+
beginWork: publication.beginWork,
|
|
724
|
+
hasUnconfirmed: publication.hasUnconfirmed,
|
|
550
725
|
capture() {
|
|
551
726
|
const authority = assistantOutputBinding.authority.captureAuthority();
|
|
552
727
|
return {
|
|
553
728
|
target: authority.target ? { ...authority.target } : undefined,
|
|
554
|
-
isCurrent: () =>
|
|
729
|
+
isCurrent: () =>
|
|
730
|
+
assistantOutputBinding.authority.isAuthorityActive(authority),
|
|
555
731
|
};
|
|
556
732
|
},
|
|
557
733
|
},
|
|
558
734
|
};
|
|
559
735
|
}
|
|
560
736
|
|
|
737
|
+
/** Fresh current work projection; a snapshot is not a cleanup grant or target-application ACK. */
|
|
738
|
+
export function createTelegramLiveTargetWorkObserver<TContext>(deps: {
|
|
739
|
+
queue: Pick<Queue.TelegramQueueStateStore<TContext>, "getQueuedItems">;
|
|
740
|
+
activeTurn: Pick<Queue.TelegramActiveTurnStore, "get">;
|
|
741
|
+
lifecycle: Pick<
|
|
742
|
+
Runtime.TelegramBridgeRuntime["lifecycle"],
|
|
743
|
+
"hasDispatchPending" | "isCompactionInProgress" | "getActiveToolExecutions"
|
|
744
|
+
>;
|
|
745
|
+
isIdle(ctx: TContext): boolean;
|
|
746
|
+
hasPendingMessages(ctx: TContext): boolean;
|
|
747
|
+
hasPendingControl(): boolean;
|
|
748
|
+
publication: Pick<
|
|
749
|
+
TelegramBridgePublicationRuntime,
|
|
750
|
+
"hasPending" | "hasUnconfirmed"
|
|
751
|
+
>;
|
|
752
|
+
activity: Pick<Activity.TelegramActivityRuntime, "hasPending">;
|
|
753
|
+
delivery: Pick<
|
|
754
|
+
ReturnType<typeof Delivery.createTelegramDeliveryLifecycleHooks>,
|
|
755
|
+
"hasPendingTarget"
|
|
756
|
+
>;
|
|
757
|
+
api: Pick<TelegramApi.TelegramApiTargetActivityRuntime, "hasPendingTarget">;
|
|
758
|
+
}): (
|
|
759
|
+
target: TelegramTarget & { threadId: number },
|
|
760
|
+
ctx: TContext,
|
|
761
|
+
) => TelegramBusLiveRebindWorkState {
|
|
762
|
+
return (target, ctx) => {
|
|
763
|
+
const work = Queue.observeTelegramTargetQueueWork(
|
|
764
|
+
target,
|
|
765
|
+
deps.activeTurn.get(),
|
|
766
|
+
deps.queue.getQueuedItems(),
|
|
767
|
+
);
|
|
768
|
+
const flags = [
|
|
769
|
+
deps.isIdle(ctx),
|
|
770
|
+
deps.hasPendingMessages(ctx),
|
|
771
|
+
deps.lifecycle.hasDispatchPending(),
|
|
772
|
+
deps.lifecycle.isCompactionInProgress(),
|
|
773
|
+
deps.hasPendingControl(),
|
|
774
|
+
];
|
|
775
|
+
const tools = deps.lifecycle.getActiveToolExecutions();
|
|
776
|
+
const publication = deps.publication.hasPending(),
|
|
777
|
+
unconfirmed = deps.publication.hasUnconfirmed?.(),
|
|
778
|
+
activity = deps.activity.hasPending?.(),
|
|
779
|
+
delivery = deps.delivery.hasPendingTarget(target),
|
|
780
|
+
api = deps.api.hasPendingTarget(target);
|
|
781
|
+
const unknown =
|
|
782
|
+
work.unknown ||
|
|
783
|
+
flags.some((flag) => typeof flag !== "boolean") ||
|
|
784
|
+
!Number.isSafeInteger(tools) ||
|
|
785
|
+
tools < 0 ||
|
|
786
|
+
unconfirmed !== false ||
|
|
787
|
+
[publication, activity, delivery, api].some(
|
|
788
|
+
(flag) => typeof flag !== "boolean",
|
|
789
|
+
);
|
|
790
|
+
return {
|
|
791
|
+
sessionBusy:
|
|
792
|
+
flags[0] !== true || flags.slice(1).some(Boolean) || tools > 0,
|
|
793
|
+
targetWork: work.protected,
|
|
794
|
+
deliveryPending:
|
|
795
|
+
publication === true ||
|
|
796
|
+
activity === true ||
|
|
797
|
+
delivery === true ||
|
|
798
|
+
api === true,
|
|
799
|
+
unknown,
|
|
800
|
+
};
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
|
|
561
804
|
interface TelegramCommandsAndToolsBindingDeps {
|
|
562
805
|
pi: Pi.ExtensionAPI;
|
|
563
806
|
agentDir: string;
|
|
@@ -567,7 +810,6 @@ interface TelegramCommandsAndToolsBindingDeps {
|
|
|
567
810
|
activeTurnRuntime: Queue.TelegramActiveTurnStore<Queue.PendingTelegramTurn>;
|
|
568
811
|
lockedPollingRuntime: Locks.TelegramLockedPollingRuntime<Pi.ExtensionContext>;
|
|
569
812
|
stopPolling?: () => Promise<void | string>;
|
|
570
|
-
recoverPollingStart?: Commands.TelegramBridgeCommandRegistrationDeps["recoverPollingStart"];
|
|
571
813
|
getDisconnectThreadName?: () => string | undefined;
|
|
572
814
|
onTransportChanged?: () => Promise<void> | void;
|
|
573
815
|
getStatusLines: (
|
|
@@ -590,8 +832,12 @@ interface TelegramCommandsAndToolsBindingDeps {
|
|
|
590
832
|
OutboundAttachments.TelegramOutboundMessageToolRegistrationDeps["sendChannelMediaMessage"]
|
|
591
833
|
>;
|
|
592
834
|
listChannelPosts: ChannelPosts.TelegramChannelPostJournalStore["list"];
|
|
593
|
-
mutateChannelPost(input: {
|
|
594
|
-
|
|
835
|
+
mutateChannelPost(input: {
|
|
836
|
+
action: "edit" | "delete";
|
|
837
|
+
operationId: string;
|
|
838
|
+
mutationId: string;
|
|
839
|
+
markdown?: string;
|
|
840
|
+
}): Promise<ChannelPosts.TelegramChannelPostRecord>;
|
|
595
841
|
callMultipart: OutboundHandlers.TelegramVoiceReplySenderDeps["sendMultipart"];
|
|
596
842
|
getDefaultChatId: () => number | undefined;
|
|
597
843
|
getDefaultTarget?: () => OutboundAttachments.TelegramQueuedOutboundAttachmentTurnView["target"];
|
|
@@ -599,13 +845,16 @@ interface TelegramCommandsAndToolsBindingDeps {
|
|
|
599
845
|
routeAgentMessage?: OutboundAttachments.TelegramOutboundMessageToolRegistrationDeps["routeAgentMessage"];
|
|
600
846
|
canSendDirect: () => boolean;
|
|
601
847
|
setGenerativeAppLiveSurfaceRuntime?: (
|
|
602
|
-
runtime:
|
|
848
|
+
runtime:
|
|
849
|
+
| GenerativeApps.GenerativeAppLiveSurfaceRuntime<GenerativeApps.TelegramBindLiveHandle>
|
|
603
850
|
| undefined,
|
|
604
851
|
) => void;
|
|
605
852
|
updateStatus: TelegramBridgeStatusUpdater;
|
|
606
853
|
isContextCurrent: (ctx: Pi.ExtensionContext) => boolean;
|
|
607
854
|
getSessionGeneration: () => number;
|
|
608
|
-
connectionIntent: NonNullable<
|
|
855
|
+
connectionIntent: NonNullable<
|
|
856
|
+
Commands.TelegramBridgeCommandRegistrationDeps["connectionIntent"]
|
|
857
|
+
>;
|
|
609
858
|
recordRuntimeEvent: TelegramRuntimeEventRecorder;
|
|
610
859
|
}
|
|
611
860
|
|
|
@@ -618,7 +867,6 @@ export function registerTelegramCommandsAndTools({
|
|
|
618
867
|
activeTurnRuntime,
|
|
619
868
|
lockedPollingRuntime,
|
|
620
869
|
stopPolling,
|
|
621
|
-
recoverPollingStart,
|
|
622
870
|
getDisconnectThreadName,
|
|
623
871
|
onTransportChanged,
|
|
624
872
|
getStatusLines,
|
|
@@ -649,23 +897,27 @@ export function registerTelegramCommandsAndTools({
|
|
|
649
897
|
? { setLiveSurfaceRuntime: setGenerativeAppLiveSurfaceRuntime }
|
|
650
898
|
: {}),
|
|
651
899
|
isDeliveryHandleCurrent: Delivery.isTelegramDeliveryHandleCurrent,
|
|
652
|
-
editView: (handle, view) =>
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
900
|
+
editView: (handle, view) =>
|
|
901
|
+
Delivery.editTelegramView(
|
|
902
|
+
handle as Delivery.TelegramDeliveryHandle,
|
|
903
|
+
view as Delivery.TelegramDeliveryView,
|
|
904
|
+
),
|
|
656
905
|
planOutput: OutboundHandlers.createTelegramOutboundReplyPlanner(
|
|
657
906
|
buttonActionStore,
|
|
658
|
-
Config.createTelegramConfigControls(configStore)
|
|
907
|
+
Config.createTelegramConfigControls(configStore)
|
|
908
|
+
.getAssistantRenderingMode,
|
|
659
909
|
),
|
|
660
910
|
sendMarkdownReply,
|
|
661
|
-
sendView: (view, options) =>
|
|
662
|
-
view as Delivery.TelegramDeliveryView,
|
|
663
|
-
options,
|
|
664
|
-
),
|
|
911
|
+
sendView: (view, options) =>
|
|
912
|
+
Delivery.sendTelegramView(view as Delivery.TelegramDeliveryView, options),
|
|
665
913
|
recordRuntimeEvent,
|
|
666
914
|
});
|
|
667
|
-
ChannelPosts.registerTelegramChannelPostMutationTool(pi, {
|
|
668
|
-
|
|
915
|
+
ChannelPosts.registerTelegramChannelPostMutationTool(pi, {
|
|
916
|
+
mutate: mutateChannelPost,
|
|
917
|
+
});
|
|
918
|
+
ChannelPosts.registerTelegramChannelPostListTool(pi, {
|
|
919
|
+
list: listChannelPosts,
|
|
920
|
+
});
|
|
669
921
|
OutboundAttachments.registerTelegramOutboundAttachmentTool(pi, {
|
|
670
922
|
getActiveTurn: activeTurnRuntime.get,
|
|
671
923
|
getDefaultChatId,
|
|
@@ -681,11 +933,11 @@ export function registerTelegramCommandsAndTools({
|
|
|
681
933
|
resolveAgentTarget,
|
|
682
934
|
routeAgentMessage,
|
|
683
935
|
canSendDirect,
|
|
684
|
-
planMessage:
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
936
|
+
planMessage: OutboundHandlers.createTelegramOutboundReplyPlanner(
|
|
937
|
+
buttonActionStore,
|
|
938
|
+
Config.createTelegramConfigControls(configStore)
|
|
939
|
+
.getAssistantRenderingMode,
|
|
940
|
+
),
|
|
689
941
|
sendMarkdownMessage: (chatId, markdown, options) =>
|
|
690
942
|
sendMarkdownReply(chatId, undefined, markdown, options),
|
|
691
943
|
sendChannelMarkdownMessage,
|
|
@@ -748,7 +1000,8 @@ export function registerTelegramCommandsAndTools({
|
|
|
748
1000
|
);
|
|
749
1001
|
}
|
|
750
1002
|
await configStore.load();
|
|
751
|
-
const latestProfile =
|
|
1003
|
+
const latestProfile =
|
|
1004
|
+
configStore.getStoredConfig().profiles?.[profileName];
|
|
752
1005
|
configStore.setProfile(profileName, {
|
|
753
1006
|
...profile,
|
|
754
1007
|
threadDisplayMode: latestProfile?.threadDisplayMode,
|
|
@@ -782,7 +1035,10 @@ export function registerTelegramCommandsAndTools({
|
|
|
782
1035
|
if (completion.status === "success") {
|
|
783
1036
|
queueAgentConnectionContext(true);
|
|
784
1037
|
if (profileName) {
|
|
785
|
-
ctx.ui.notify(
|
|
1038
|
+
ctx.ui.notify(
|
|
1039
|
+
`Profile "${profileName}" saved and connected.`,
|
|
1040
|
+
"info",
|
|
1041
|
+
);
|
|
786
1042
|
}
|
|
787
1043
|
}
|
|
788
1044
|
},
|
|
@@ -791,9 +1047,9 @@ export function registerTelegramCommandsAndTools({
|
|
|
791
1047
|
hasBotToken: configStore.hasBotToken,
|
|
792
1048
|
getBotTokenDiagnostic: configStore.getBotTokenDiagnostic,
|
|
793
1049
|
startPolling: lockedPollingRuntime.start,
|
|
794
|
-
recordConnectionEvent: (error, phase) =>
|
|
1050
|
+
recordConnectionEvent: (error, phase) =>
|
|
1051
|
+
recordRuntimeEvent("connection", error, { phase }),
|
|
795
1052
|
stopPolling: stopPolling ?? lockedPollingRuntime.stop,
|
|
796
|
-
recoverPollingStart,
|
|
797
1053
|
getDisconnectThreadName,
|
|
798
1054
|
queueAgentConnectionContext,
|
|
799
1055
|
updateStatus,
|
|
@@ -839,7 +1095,11 @@ interface TelegramLifecycleBindingDeps {
|
|
|
839
1095
|
diagnostics?: { onSessionStart(): void; onSessionShutdown(): Promise<void> };
|
|
840
1096
|
assistantOutputRuntime: Pick<
|
|
841
1097
|
Activity.TelegramAssistantOutputRuntime,
|
|
842
|
-
|
|
1098
|
+
| "start"
|
|
1099
|
+
| "beginTurn"
|
|
1100
|
+
| "hasAdmittedTelegramIntermediate"
|
|
1101
|
+
| "waitForIdle"
|
|
1102
|
+
| "stop"
|
|
843
1103
|
>;
|
|
844
1104
|
sessionLifecycleRuntime: Pick<
|
|
845
1105
|
Lifecycle.TelegramLifecycleRegistrationDeps,
|
|
@@ -866,7 +1126,10 @@ interface TelegramLifecycleBindingDeps {
|
|
|
866
1126
|
deferredQueueDispatchRuntime: Queue.TelegramDeferredQueueDispatchRuntime<Pi.ExtensionContext>;
|
|
867
1127
|
modelContextAvailabilityRuntime: Prompts.TelegramModelContextAvailabilityRuntime;
|
|
868
1128
|
disconnectOnQuit?: () => Promise<unknown>;
|
|
869
|
-
onSessionStarted?: (
|
|
1129
|
+
onSessionStarted?: (
|
|
1130
|
+
event: Pi.SessionStartEvent,
|
|
1131
|
+
ctx: Pi.ExtensionContext,
|
|
1132
|
+
) => void;
|
|
870
1133
|
shutdownGenerativeAppLiveSurfaces?: () => void;
|
|
871
1134
|
resolveAutomaticThreadCleanupEnabled?: () => boolean | Promise<boolean>;
|
|
872
1135
|
buttonActionStore: OutboundHandlers.TelegramButtonActionStore;
|
|
@@ -1113,16 +1376,20 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1113
1376
|
{ replyToPrompt: false },
|
|
1114
1377
|
);
|
|
1115
1378
|
};
|
|
1116
|
-
let pendingFinalPublication:
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1379
|
+
let pendingFinalPublication:
|
|
1380
|
+
| {
|
|
1381
|
+
turn: Queue.PendingTelegramTurn;
|
|
1382
|
+
reservation: Activity.TelegramActivityPublicationReservation;
|
|
1383
|
+
}
|
|
1384
|
+
| undefined;
|
|
1120
1385
|
const cancelPendingFinalPublication = (): void => {
|
|
1121
1386
|
pendingFinalPublication?.reservation.cancel();
|
|
1122
1387
|
pendingFinalPublication = undefined;
|
|
1123
1388
|
};
|
|
1124
1389
|
const recordPublicationFailure = (error: unknown): void => {
|
|
1125
|
-
recordRuntimeEvent("delivery", error, {
|
|
1390
|
+
recordRuntimeEvent("delivery", error, {
|
|
1391
|
+
phase: "agent-end-background-delivery",
|
|
1392
|
+
});
|
|
1126
1393
|
};
|
|
1127
1394
|
const scheduleActiveTurnDelivery = (task: () => Promise<void>): void => {
|
|
1128
1395
|
void publicationRuntime.enqueue(task).catch(recordPublicationFailure);
|
|
@@ -1159,7 +1426,8 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1159
1426
|
loadConfig: configStore.load,
|
|
1160
1427
|
extractAssistant: Replies.extractRunAssistantMessage,
|
|
1161
1428
|
isAssistantAlreadyPublished: (assistant) =>
|
|
1162
|
-
!!assistant.text &&
|
|
1429
|
+
!!assistant.text &&
|
|
1430
|
+
assistantOutputRuntime.hasAdmittedTelegramIntermediate(assistant.text),
|
|
1163
1431
|
getFoldQueuedPromptsIntoHistory:
|
|
1164
1432
|
lifecycle.shouldFoldQueuedPromptsIntoHistory,
|
|
1165
1433
|
resetRuntimeState: agentEndResetter,
|
|
@@ -1175,9 +1443,12 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1175
1443
|
pendingFinalPublication = undefined;
|
|
1176
1444
|
const matches = pending?.turn === activeTurnRuntime.get();
|
|
1177
1445
|
if (!matches) pending?.reservation.cancel();
|
|
1178
|
-
const reservation =
|
|
1446
|
+
const reservation =
|
|
1447
|
+
matches && pending ? pending.reservation : publicationRuntime.reserve();
|
|
1179
1448
|
return {
|
|
1180
|
-
schedule: (task) => {
|
|
1449
|
+
schedule: (task) => {
|
|
1450
|
+
void reservation.publish(task).catch(recordPublicationFailure);
|
|
1451
|
+
},
|
|
1181
1452
|
cancel: reservation.cancel,
|
|
1182
1453
|
};
|
|
1183
1454
|
},
|
|
@@ -1203,9 +1474,9 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1203
1474
|
setActiveToolExecutions: lifecycle.setActiveToolExecutions,
|
|
1204
1475
|
triggerPendingModelSwitchAbort: modelSwitchController.triggerPendingAbort,
|
|
1205
1476
|
});
|
|
1206
|
-
Lifecycle.setResetTransportReplyDedup(Replies.resetTransportReplyDedup);
|
|
1207
1477
|
const agentStartWithDedupReset = Lifecycle.createAgentStartDedupHook(
|
|
1208
1478
|
agentLifecycleHooks.onAgentStart,
|
|
1479
|
+
Replies.resetTransportReplyDedup,
|
|
1209
1480
|
scheduleActiveTurnDelivery,
|
|
1210
1481
|
);
|
|
1211
1482
|
let uiPromptActive = false;
|
|
@@ -1230,23 +1501,32 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1230
1501
|
};
|
|
1231
1502
|
let observedAutomaticCompaction = false;
|
|
1232
1503
|
let agentWorkActive = false;
|
|
1233
|
-
const prepareCompactionNotice = (
|
|
1504
|
+
const prepareCompactionNotice = (
|
|
1505
|
+
text: string,
|
|
1506
|
+
ctx: Pi.ExtensionContext,
|
|
1507
|
+
): (() => Promise<void>) => {
|
|
1234
1508
|
const authority = publicationRuntime.capture();
|
|
1235
1509
|
const turn = activeTurnRuntime.get();
|
|
1236
1510
|
const selectedTarget = turn?.target ?? authority.target;
|
|
1237
1511
|
const target = selectedTarget ? { ...selectedTarget } : undefined;
|
|
1238
1512
|
const replyToMessageId = turn?.replyToMessageId;
|
|
1239
1513
|
return async () => {
|
|
1240
|
-
if (!target || !isSessionContextActive(ctx) || !authority.isCurrent())
|
|
1514
|
+
if (!target || !isSessionContextActive(ctx) || !authority.isCurrent())
|
|
1515
|
+
return;
|
|
1241
1516
|
if (turn && isTurnTransportActive?.(turn) === false) return;
|
|
1242
1517
|
try {
|
|
1243
|
-
await sendMarkdownReply(target.chatId, replyToMessageId, text, {
|
|
1518
|
+
await sendMarkdownReply(target.chatId, replyToMessageId, text, {
|
|
1519
|
+
target,
|
|
1520
|
+
});
|
|
1244
1521
|
} catch (error) {
|
|
1245
1522
|
recordRuntimeEvent("delivery", error, { phase: "compaction-notice" });
|
|
1246
1523
|
}
|
|
1247
1524
|
};
|
|
1248
1525
|
};
|
|
1249
|
-
const sendCompactionNotice = (
|
|
1526
|
+
const sendCompactionNotice = (
|
|
1527
|
+
text: string,
|
|
1528
|
+
ctx: Pi.ExtensionContext,
|
|
1529
|
+
): void => {
|
|
1250
1530
|
scheduleActiveTurnDelivery(prepareCompactionNotice(text, ctx));
|
|
1251
1531
|
};
|
|
1252
1532
|
const compactionObserver = Lifecycle.createTelegramCompactionObserverRuntime({
|
|
@@ -1325,7 +1605,11 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1325
1605
|
if (shouldNotify) observedAutomaticCompaction = true;
|
|
1326
1606
|
activityRuntime.onCompactionStart(Pi.getSessionCompactionReason(event));
|
|
1327
1607
|
compactionObserver.onSessionBeforeCompact(event, ctx);
|
|
1328
|
-
if (shouldNotify)
|
|
1608
|
+
if (shouldNotify)
|
|
1609
|
+
sendCompactionNotice(
|
|
1610
|
+
Commands.TELEGRAM_COMPACTION_STARTED_MARKDOWN,
|
|
1611
|
+
ctx,
|
|
1612
|
+
);
|
|
1329
1613
|
},
|
|
1330
1614
|
async onSessionCompact(event, ctx) {
|
|
1331
1615
|
if (!isSessionContextActive(ctx)) return;
|
|
@@ -1333,7 +1617,10 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1333
1617
|
compactionObserver.onSessionCompact(event, ctx);
|
|
1334
1618
|
if (observedAutomaticCompaction) {
|
|
1335
1619
|
observedAutomaticCompaction = false;
|
|
1336
|
-
sendCompactionNotice(
|
|
1620
|
+
sendCompactionNotice(
|
|
1621
|
+
Commands.TELEGRAM_COMPACTION_COMPLETED_MARKDOWN,
|
|
1622
|
+
ctx,
|
|
1623
|
+
);
|
|
1337
1624
|
}
|
|
1338
1625
|
},
|
|
1339
1626
|
async onSessionCompactFailed(event, ctx) {
|
|
@@ -1401,13 +1688,29 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1401
1688
|
previewRuntime.seal();
|
|
1402
1689
|
activityRuntime.onAssistantMessageEnd(event.message.stopReason);
|
|
1403
1690
|
}
|
|
1404
|
-
if (
|
|
1691
|
+
if (
|
|
1692
|
+
event.message.role !== "assistant" ||
|
|
1693
|
+
event.message.stopReason === "toolUse" ||
|
|
1694
|
+
event.message.stopReason === "aborted"
|
|
1695
|
+
)
|
|
1696
|
+
return;
|
|
1405
1697
|
const turn = activeTurnRuntime.get();
|
|
1406
|
-
if (!turn || turn.guestQueryId || pendingFinalPublication?.turn === turn)
|
|
1698
|
+
if (!turn || turn.guestQueryId || pendingFinalPublication?.turn === turn)
|
|
1699
|
+
return;
|
|
1407
1700
|
cancelPendingFinalPublication();
|
|
1408
|
-
const assistant = Replies.extractLatestAssistantMessageText([
|
|
1409
|
-
|
|
1410
|
-
|
|
1701
|
+
const assistant = Replies.extractLatestAssistantMessageText([
|
|
1702
|
+
event.message,
|
|
1703
|
+
]);
|
|
1704
|
+
if (
|
|
1705
|
+
!assistant.text &&
|
|
1706
|
+
assistant.stopReason !== "error" &&
|
|
1707
|
+
turn.queuedAttachments.length === 0
|
|
1708
|
+
)
|
|
1709
|
+
return;
|
|
1710
|
+
pendingFinalPublication = {
|
|
1711
|
+
turn,
|
|
1712
|
+
reservation: publicationRuntime.reserve(),
|
|
1713
|
+
};
|
|
1411
1714
|
},
|
|
1412
1715
|
onUiPromptStart(event, ctx) {
|
|
1413
1716
|
if (!isSessionContextActive(ctx)) return;
|
|
@@ -1427,7 +1730,10 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1427
1730
|
},
|
|
1428
1731
|
async onAgentEnd(event, ctx) {
|
|
1429
1732
|
if (!isSessionContextActive(ctx)) return;
|
|
1430
|
-
if (
|
|
1733
|
+
if (
|
|
1734
|
+
pendingFinalPublication &&
|
|
1735
|
+
pendingFinalPublication.turn !== activeTurnRuntime.get()
|
|
1736
|
+
) {
|
|
1431
1737
|
cancelPendingFinalPublication();
|
|
1432
1738
|
return;
|
|
1433
1739
|
}
|
|
@@ -1440,7 +1746,8 @@ export function registerTelegramLifecycleRuntimeHooks({
|
|
|
1440
1746
|
try {
|
|
1441
1747
|
await agentLifecycleHooks.onAgentSettled(event, ctx);
|
|
1442
1748
|
} finally {
|
|
1443
|
-
if (pendingFinalPublication === pending)
|
|
1749
|
+
if (pendingFinalPublication === pending)
|
|
1750
|
+
cancelPendingFinalPublication();
|
|
1444
1751
|
}
|
|
1445
1752
|
if (!isSessionContextActive(ctx)) return;
|
|
1446
1753
|
agentWorkActive = false;
|