@llblab/pi-telegram 0.52.2 → 0.53.0
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 +11 -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 +61 -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 +249 -126
- 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 +125 -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 +511 -300
- 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/dist/lib/menu-status.js
CHANGED
|
@@ -4,26 +4,13 @@
|
|
|
4
4
|
* Owns status-menu payloads, status callback handling, and status-menu message rendering
|
|
5
5
|
*/
|
|
6
6
|
import { formatTelegramCommandEmojiPrefix } from "./commands.js";
|
|
7
|
-
import {
|
|
8
|
-
import { formatStatusButtonLabel, } from "./menu-model.js";
|
|
7
|
+
import { refuseUnavailableTelegramThinkingControls } from "./menu-thinking.js";
|
|
8
|
+
import { editTelegramMenuMessage, formatStatusButtonLabel, sendTelegramMenuMessage, } from "./menu-model.js";
|
|
9
9
|
import { getCanonicalModelId, } from "./model.js";
|
|
10
|
+
import { getTelegramSectionMainMenuRows, } from "./sections.js";
|
|
10
11
|
function isTelegramStatusMenuCallbackAction(data, action) {
|
|
11
12
|
return data === `menu:${action}` || data === `status:${action}`;
|
|
12
13
|
}
|
|
13
|
-
function applyTelegramMenuRenderPayload(state, payload) {
|
|
14
|
-
state.mode = payload.nextMode;
|
|
15
|
-
return payload;
|
|
16
|
-
}
|
|
17
|
-
async function editTelegramMenuMessage(state, payload, deps) {
|
|
18
|
-
const appliedPayload = applyTelegramMenuRenderPayload(state, payload);
|
|
19
|
-
await deps.editInteractiveMessage(state.chatId, state.messageId, appliedPayload.text, appliedPayload.mode, appliedPayload.replyMarkup);
|
|
20
|
-
}
|
|
21
|
-
function sendTelegramMenuMessage(state, payload, deps) {
|
|
22
|
-
const appliedPayload = applyTelegramMenuRenderPayload(state, payload);
|
|
23
|
-
return deps.sendInteractiveMessage(state.chatId, appliedPayload.text, appliedPayload.mode, appliedPayload.replyMarkup, state.threadId !== undefined
|
|
24
|
-
? { target: { chatId: state.chatId, threadId: state.threadId } }
|
|
25
|
-
: undefined);
|
|
26
|
-
}
|
|
27
14
|
export async function openTelegramStatusMenu(deps) {
|
|
28
15
|
const state = await deps.getModelMenuState();
|
|
29
16
|
const messageId = await deps.sendStatusMenu(state, deps.buildStatusHtml(), deps.getActiveModel(), deps.getThinkingLevel(), deps.getQueueItemCount?.() ?? 0);
|
|
@@ -48,14 +35,8 @@ export async function handleTelegramStatusMenuCallbackAction(callbackQueryId, da
|
|
|
48
35
|
}
|
|
49
36
|
if (!isTelegramStatusMenuCallbackAction(data, "thinking"))
|
|
50
37
|
return false;
|
|
51
|
-
if (deps
|
|
52
|
-
await deps.answerCallbackQuery(callbackQueryId, "Thinking controls are disabled during voice replies.");
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
if (!activeModel?.reasoning) {
|
|
56
|
-
await deps.answerCallbackQuery(callbackQueryId, "This model has no reasoning controls.");
|
|
38
|
+
if (await refuseUnavailableTelegramThinkingControls(callbackQueryId, activeModel, deps))
|
|
57
39
|
return true;
|
|
58
|
-
}
|
|
59
40
|
await deps.updateThinkingMenuMessage();
|
|
60
41
|
await deps.answerCallbackQuery(callbackQueryId);
|
|
61
42
|
return true;
|
|
@@ -83,10 +64,12 @@ export function buildStatusReplyMarkup(activeModel, currentThinkingLevel, queueI
|
|
|
83
64
|
},
|
|
84
65
|
]);
|
|
85
66
|
if (pendingCancellationCount > 0)
|
|
86
|
-
rows.push([
|
|
67
|
+
rows.push([
|
|
68
|
+
{
|
|
87
69
|
text: `❌ Pending cancellations: ${pendingCancellationCount}`,
|
|
88
70
|
callback_data: "reroutecancel:review:open",
|
|
89
|
-
}
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
90
73
|
if (sectionRegistry) {
|
|
91
74
|
const sectionRows = getTelegramSectionMainMenuRows(sectionRegistry);
|
|
92
75
|
for (const row of sectionRows) {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Zones: telegram ui, thinking controls, menu composition
|
|
4
4
|
* Owns thinking-menu text, reply markup, callback handling, and thinking-menu message rendering
|
|
5
5
|
*/
|
|
6
|
-
import type
|
|
6
|
+
import { type TelegramMenuMessageRuntimeDeps, type TelegramMenuRenderPayload, type TelegramModelMenuState, type TelegramReplyMarkup } from "./menu-model.ts";
|
|
7
7
|
import { type MenuModel, type ThinkingLevel } from "./model.ts";
|
|
8
8
|
export interface TelegramThinkingMenuCallbackDeps {
|
|
9
9
|
setThinkingLevel: (level: ThinkingLevel) => void;
|
|
@@ -19,6 +19,11 @@ export interface TelegramThinkingMenuOpenDeps<TModel extends MenuModel = MenuMod
|
|
|
19
19
|
storeModelMenuState: (state: TelegramModelMenuState<TModel>) => void;
|
|
20
20
|
isVoiceReplyActive?: () => boolean;
|
|
21
21
|
}
|
|
22
|
+
/** Answers and returns true when voice replies or a non-reasoning model disable thinking controls. */
|
|
23
|
+
export declare function refuseUnavailableTelegramThinkingControls(callbackQueryId: string, activeModel: MenuModel | undefined, deps: {
|
|
24
|
+
answerCallbackQuery: (callbackQueryId: string, text?: string) => Promise<void>;
|
|
25
|
+
isVoiceReplyActive?: () => boolean;
|
|
26
|
+
}): Promise<boolean>;
|
|
22
27
|
export declare function handleTelegramThinkingMenuCallbackAction(callbackQueryId: string, data: string | undefined, activeModel: MenuModel | undefined, deps: TelegramThinkingMenuCallbackDeps): Promise<boolean>;
|
|
23
28
|
export declare function buildThinkingMenuText(): string;
|
|
24
29
|
export declare function buildThinkingMenuReplyMarkup(currentThinkingLevel: ThinkingLevel): TelegramReplyMarkup;
|
|
@@ -3,42 +3,35 @@
|
|
|
3
3
|
* Zones: telegram ui, thinking controls, menu composition
|
|
4
4
|
* Owns thinking-menu text, reply markup, callback handling, and thinking-menu message rendering
|
|
5
5
|
*/
|
|
6
|
+
import { editTelegramMenuMessage, sendTelegramMenuMessage, } from "./menu-model.js";
|
|
6
7
|
import { isThinkingLevel, THINKING_LEVELS, } from "./model.js";
|
|
7
8
|
function parseTelegramThinkingMenuCallbackAction(data) {
|
|
8
9
|
if (!data?.startsWith("thinking:set:"))
|
|
9
10
|
return undefined;
|
|
10
11
|
return { kind: "thinking:set", level: data.slice("thinking:set:".length) };
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return
|
|
23
|
-
? { target: { chatId: state.chatId, threadId: state.threadId } }
|
|
24
|
-
: undefined);
|
|
13
|
+
/** Answers and returns true when voice replies or a non-reasoning model disable thinking controls. */
|
|
14
|
+
export async function refuseUnavailableTelegramThinkingControls(callbackQueryId, activeModel, deps) {
|
|
15
|
+
if (deps.isVoiceReplyActive?.()) {
|
|
16
|
+
await deps.answerCallbackQuery(callbackQueryId, "Thinking controls are disabled during voice replies");
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
if (!activeModel?.reasoning) {
|
|
20
|
+
await deps.answerCallbackQuery(callbackQueryId, "This model has no reasoning controls");
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
25
24
|
}
|
|
26
25
|
export async function handleTelegramThinkingMenuCallbackAction(callbackQueryId, data, activeModel, deps) {
|
|
27
26
|
const action = parseTelegramThinkingMenuCallbackAction(data);
|
|
28
27
|
if (!action)
|
|
29
28
|
return false;
|
|
30
29
|
if (!isThinkingLevel(action.level)) {
|
|
31
|
-
await deps.answerCallbackQuery(callbackQueryId, "Invalid thinking level
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
if (deps.isVoiceReplyActive?.()) {
|
|
35
|
-
await deps.answerCallbackQuery(callbackQueryId, "Thinking controls are disabled during voice replies.");
|
|
30
|
+
await deps.answerCallbackQuery(callbackQueryId, "Invalid thinking level");
|
|
36
31
|
return true;
|
|
37
32
|
}
|
|
38
|
-
if (
|
|
39
|
-
await deps.answerCallbackQuery(callbackQueryId, "This model has no reasoning controls.");
|
|
33
|
+
if (await refuseUnavailableTelegramThinkingControls(callbackQueryId, activeModel, deps))
|
|
40
34
|
return true;
|
|
41
|
-
}
|
|
42
35
|
deps.setThinkingLevel(action.level);
|
|
43
36
|
await deps.updateThinkingMenuMessage();
|
|
44
37
|
await deps.answerCallbackQuery(callbackQueryId, `Thinking: ${deps.getCurrentThinkingLevel()}`);
|
package/dist/lib/menu.d.ts
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
* Zones: telegram ui, controls, status menu
|
|
4
4
|
* Owns app-menu/status state, inline UI text, and callback composition while model/thinking/queue menu details live in dedicated domains
|
|
5
5
|
*/
|
|
6
|
-
import { type TelegramMenuMessageRuntimeDeps, type TelegramModelMenuState, type
|
|
6
|
+
import { type TelegramMenuMessageRuntimeDeps, type TelegramModelMenuState, type TelegramReplyMarkup } from "./menu-model.ts";
|
|
7
7
|
import { type MenuModel, type ScopedTelegramModel, type TelegramModelSwitchContinuationSource, type ThinkingLevel } from "./model.ts";
|
|
8
|
-
import type { TelegramInputRichMessage } from "./telegram-api.ts";
|
|
9
8
|
import { type TelegramSectionRegistry } from "./sections.ts";
|
|
9
|
+
import type { TelegramApiCallOptions, TelegramInputRichMessage } from "./telegram-api.ts";
|
|
10
10
|
export { applyTelegramModelPageSelection, applyTelegramModelScopeSelection, buildModelMenuReplyMarkup, buildModelPageMenuReplyMarkup, buildTelegramModelCallbackPlan, buildTelegramModelMenuRenderPayload, buildTelegramModelMenuState, buildTelegramModelMenuStateRuntime, buildTelegramModelPageMenuRenderPayload, createTelegramModelMenuRuntime, createTelegramModelMenuStateBuilder, formatScopedModelButtonText, getModelMenuItems, getStoredTelegramModelMenuState, getTelegramModelMenuPage, getTelegramModelSelection, handleTelegramModelMenuCallbackAction, MODEL_MENU_TITLE, MODEL_PAGE_MENU_TITLE, openTelegramModelMenu, pruneStoredTelegramModelMenus, resolveCachedTelegramModelMenuInputs, sendTelegramModelMenuMessage, storeTelegramModelMenuState, TELEGRAM_MODEL_PAGE_SIZE, updateTelegramModelMenuMessage, } from "./menu-model.ts";
|
|
11
11
|
export type { BuildTelegramModelCallbackPlanParams, BuildTelegramModelMenuStateParams, CachedTelegramModelMenuInputs, MenuSettingsManager, StoredTelegramModelMenuState, TelegramMenuMessageRuntimeDeps, TelegramMenuMutationResult, TelegramMenuRenderPayload, TelegramMenuSelectionResult, TelegramModelCallbackPlan, TelegramModelMenuCallbackDeps, TelegramModelMenuInputCacheDeps, TelegramModelMenuOpenDeps, TelegramModelMenuPage, TelegramModelMenuRuntime, TelegramModelMenuRuntimeContext, TelegramModelMenuRuntimeOptions, TelegramModelMenuState, TelegramModelMenuStateBuilderContext, TelegramModelMenuStateBuilderDeps, TelegramModelMenuStoreOptions, TelegramModelScope, TelegramReplyMarkup, } from "./menu-model.ts";
|
|
12
12
|
export { buildStatusReplyMarkup, buildTelegramStatusMenuRenderPayload, handleTelegramStatusMenuCallbackAction, openTelegramStatusMenu, sendTelegramStatusMessage, updateTelegramStatusMessage, } from "./menu-status.ts";
|
|
@@ -93,6 +93,7 @@ export interface TelegramMenuActionRuntimeDeps<TContext, TModel extends MenuMode
|
|
|
93
93
|
threadId?: number;
|
|
94
94
|
};
|
|
95
95
|
parseMode?: "HTML";
|
|
96
|
+
assertAuthority?: TelegramApiCallOptions["assertAuthority"];
|
|
96
97
|
}) => Promise<unknown>;
|
|
97
98
|
sectionRegistry?: TelegramSectionRegistry;
|
|
98
99
|
isVoiceReplyActive?: () => boolean;
|
|
@@ -101,70 +102,16 @@ export interface TelegramMenuActionRuntime<TContext, TModel extends MenuModel =
|
|
|
101
102
|
updateModelMenuMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
102
103
|
updateThinkingMenuMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
103
104
|
updateStatusMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
104
|
-
sendStatusMessage: (chatId: number, replyToMessageId: number, ctx: TContext, threadId?: number) => Promise<void>;
|
|
105
|
-
openModelMenu: (chatId: number, replyToMessageId: number, ctx: TContext, threadId?: number) => Promise<void>;
|
|
106
|
-
openThinkingMenu: (chatId: number, replyToMessageId: number, ctx: TContext) => Promise<void>;
|
|
105
|
+
sendStatusMessage: (chatId: number, replyToMessageId: number, ctx: TContext, threadId?: number, options?: Pick<TelegramApiCallOptions, "assertAuthority">) => Promise<void>;
|
|
106
|
+
openModelMenu: (chatId: number, replyToMessageId: number, ctx: TContext, threadId?: number, options?: Pick<TelegramApiCallOptions, "assertAuthority">) => Promise<void>;
|
|
107
|
+
openThinkingMenu: (chatId: number, replyToMessageId: number, ctx: TContext, threadId?: number, options?: Pick<TelegramApiCallOptions, "assertAuthority">) => Promise<void>;
|
|
107
108
|
}
|
|
108
|
-
export type TelegramMenuCallbackAction = {
|
|
109
|
-
kind: "ignore";
|
|
110
|
-
} | {
|
|
111
|
-
kind: "status";
|
|
112
|
-
action: "model" | "thinking" | "queue" | "settings";
|
|
113
|
-
} | {
|
|
114
|
-
kind: "thinking:set";
|
|
115
|
-
level: string;
|
|
116
|
-
} | {
|
|
117
|
-
kind: "model";
|
|
118
|
-
action: "noop" | "scope" | "page" | "pages" | "open" | "pick" | "pick-selected" | "scope-enable" | "scope-disable" | "scope-toggle";
|
|
119
|
-
value?: string;
|
|
120
|
-
};
|
|
121
|
-
export declare function parseTelegramMenuCallbackAction(data: string | undefined): TelegramMenuCallbackAction;
|
|
122
109
|
export declare function handleTelegramMenuCallbackEntry(callbackQueryId: string, data: string | undefined, state: TelegramModelMenuState | undefined, deps: TelegramMenuCallbackEntryDeps): Promise<void>;
|
|
123
110
|
export declare function handleStoredTelegramMenuCallback<TModel extends MenuModel = MenuModel>(query: MenuCallbackQuery, deps: StoredTelegramMenuCallbackDeps<TModel>): Promise<void>;
|
|
124
|
-
export
|
|
125
|
-
getStoredModelMenuState: (messageId: number | undefined, chatId?: number) => TelegramModelMenuState<TModel> | undefined;
|
|
126
|
-
getActiveModel: (ctx: TContext) => TModel | undefined;
|
|
127
|
-
getThinkingLevel: () => ThinkingLevel;
|
|
128
|
-
setThinkingLevel: (level: ThinkingLevel) => void;
|
|
129
|
-
updateStatus: (ctx: TContext, error?: string) => void;
|
|
130
|
-
updateModelMenuMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
131
|
-
updateThinkingMenuMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
132
|
-
updateStatusMessage: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
133
|
-
updateSettingsMenuMessage?: (state: TelegramModelMenuState<TModel>, ctx: TContext) => Promise<void>;
|
|
134
|
-
answerCallbackQuery: (callbackQueryId: string, text?: string) => Promise<void>;
|
|
135
|
-
isIdle: (ctx: TContext) => boolean;
|
|
136
|
-
hasAbortHandler: () => boolean;
|
|
111
|
+
export type TelegramMenuCallbackRuntimeAdapterDeps<TContext, TModel extends MenuModel = MenuModel> = Omit<TelegramMenuCallbackRuntimeDeps<TContext, TModel>, "hasActiveToolExecutions"> & {
|
|
137
112
|
getActiveToolExecutions: () => number;
|
|
138
|
-
|
|
139
|
-
setModel: (model: TModel) => Promise<boolean>;
|
|
140
|
-
setCurrentModel: (model: TModel, ctx: TContext) => void;
|
|
141
|
-
stagePendingModelSwitch: (selection: ScopedTelegramModel<TModel>, ctx: TContext, continuationTurn: TelegramModelSwitchContinuationSource) => void;
|
|
142
|
-
restartInterruptedTelegramTurn: (selection: ScopedTelegramModel<TModel>, ctx: TContext, continuationTurn: TelegramModelSwitchContinuationSource) => Promise<boolean> | boolean;
|
|
143
|
-
sectionRegistry?: TelegramSectionRegistry;
|
|
144
|
-
editInteractiveMessage?: (chatId: number, messageId: number, text: string, mode: "markdown" | "html" | "plain", replyMarkup: TelegramReplyMarkup) => Promise<void>;
|
|
145
|
-
sendInteractiveMessage?: (chatId: number, text: string, mode: "markdown" | "html" | "plain", replyMarkup: TelegramReplyMarkup, options?: {
|
|
146
|
-
target?: {
|
|
147
|
-
chatId: number;
|
|
148
|
-
threadId?: number;
|
|
149
|
-
};
|
|
150
|
-
}) => Promise<number | undefined>;
|
|
151
|
-
sendSectionRichMessage?: (chatId: number, message: TelegramInputRichMessage, options?: {
|
|
152
|
-
target?: {
|
|
153
|
-
chatId: number;
|
|
154
|
-
threadId?: number;
|
|
155
|
-
};
|
|
156
|
-
}) => Promise<number | undefined>;
|
|
157
|
-
enqueueSectionPrompt?: (prompt: string, ctx: TContext, target?: {
|
|
158
|
-
chatId: number;
|
|
159
|
-
threadId?: number;
|
|
160
|
-
}, source?: unknown) => Promise<void>;
|
|
161
|
-
deleteMessage?: (chatId: number, messageId: number) => Promise<void>;
|
|
162
|
-
}
|
|
113
|
+
};
|
|
163
114
|
export declare function createTelegramMenuCallbackHandler<TQuery extends MenuCallbackQuery, TContext, TModel extends MenuModel = MenuModel>(deps: TelegramMenuCallbackRuntimeDeps<TContext, TModel>): (query: TQuery, ctx: TContext) => Promise<void>;
|
|
164
115
|
export declare function createTelegramMenuCallbackHandlerForContext<TQuery extends MenuCallbackQuery, TContext, TModel extends MenuModel = MenuModel>(deps: TelegramMenuCallbackRuntimeAdapterDeps<TContext, TModel>): (query: TQuery, ctx: TContext) => Promise<void>;
|
|
165
116
|
export declare function handleTelegramMenuCallbackRuntime<TQuery extends MenuCallbackQuery, TContext, TModel extends MenuModel = MenuModel>(query: TQuery, ctx: TContext, deps: TelegramMenuCallbackRuntimeDeps<TContext, TModel>): Promise<void>;
|
|
166
|
-
export interface TelegramMenuActionRuntimeWithStateBuilderDeps<TModel extends MenuModel = MenuModel, TContext extends TelegramModelMenuStateBuilderContext<TModel> = TelegramModelMenuStateBuilderContext<TModel>> extends Omit<TelegramMenuActionRuntimeDeps<TContext, TModel>, "getModelMenuState">, TelegramModelMenuStateBuilderDeps<TModel, TContext> {
|
|
167
|
-
isVoiceReplyActive?: () => boolean;
|
|
168
|
-
}
|
|
169
|
-
export declare function createTelegramMenuActionRuntimeWithStateBuilder<TModel extends MenuModel = MenuModel, TContext extends TelegramModelMenuStateBuilderContext<TModel> = TelegramModelMenuStateBuilderContext<TModel>>(deps: TelegramMenuActionRuntimeWithStateBuilderDeps<TModel, TContext>): TelegramMenuActionRuntime<TContext, TModel>;
|
|
170
117
|
export declare function createTelegramMenuActionRuntime<TContext, TModel extends MenuModel = MenuModel>(deps: TelegramMenuActionRuntimeDeps<TContext, TModel>): TelegramMenuActionRuntime<TContext, TModel>;
|
package/dist/lib/menu.js
CHANGED
|
@@ -3,56 +3,20 @@
|
|
|
3
3
|
* Zones: telegram ui, controls, status menu
|
|
4
4
|
* Owns app-menu/status state, inline UI text, and callback composition while model/thinking/queue menu details live in dedicated domains
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { createTelegramMenuDelivery, handleTelegramModelMenuCallbackAction, openTelegramModelMenu, sendTelegramModelMenuMessage, updateTelegramModelMenuMessage, } from "./menu-model.js";
|
|
7
7
|
import { handleTelegramStatusMenuCallbackAction, openTelegramStatusMenu, sendTelegramStatusMessage, updateTelegramStatusMessage, } from "./menu-status.js";
|
|
8
8
|
import { handleTelegramThinkingMenuCallbackAction, openTelegramThinkingMenu, updateTelegramThinkingMenuMessage, } from "./menu-thinking.js";
|
|
9
9
|
import { handleTelegramSectionCallback, handleTelegramSectionOpen, handleTelegramSectionSettingsOpen, parseTelegramSectionCallback, } from "./sections.js";
|
|
10
10
|
export { applyTelegramModelPageSelection, applyTelegramModelScopeSelection, buildModelMenuReplyMarkup, buildModelPageMenuReplyMarkup, buildTelegramModelCallbackPlan, buildTelegramModelMenuRenderPayload, buildTelegramModelMenuState, buildTelegramModelMenuStateRuntime, buildTelegramModelPageMenuRenderPayload, createTelegramModelMenuRuntime, createTelegramModelMenuStateBuilder, formatScopedModelButtonText, getModelMenuItems, getStoredTelegramModelMenuState, getTelegramModelMenuPage, getTelegramModelSelection, handleTelegramModelMenuCallbackAction, MODEL_MENU_TITLE, MODEL_PAGE_MENU_TITLE, openTelegramModelMenu, pruneStoredTelegramModelMenus, resolveCachedTelegramModelMenuInputs, sendTelegramModelMenuMessage, storeTelegramModelMenuState, TELEGRAM_MODEL_PAGE_SIZE, updateTelegramModelMenuMessage, } from "./menu-model.js";
|
|
11
11
|
export { buildStatusReplyMarkup, buildTelegramStatusMenuRenderPayload, handleTelegramStatusMenuCallbackAction, openTelegramStatusMenu, sendTelegramStatusMessage, updateTelegramStatusMessage, } from "./menu-status.js";
|
|
12
12
|
export { buildTelegramThinkingMenuRenderPayload, buildThinkingMenuReplyMarkup, buildThinkingMenuText, handleTelegramThinkingMenuCallbackAction, openTelegramThinkingMenu, updateTelegramThinkingMenuMessage, } from "./menu-thinking.js";
|
|
13
|
-
export function parseTelegramMenuCallbackAction(data) {
|
|
14
|
-
if (data === "menu:model" || data === "status:model") {
|
|
15
|
-
return { kind: "status", action: "model" };
|
|
16
|
-
}
|
|
17
|
-
if (data === "menu:thinking" || data === "status:thinking") {
|
|
18
|
-
return { kind: "status", action: "thinking" };
|
|
19
|
-
}
|
|
20
|
-
if (data === "menu:queue" || data === "status:queue") {
|
|
21
|
-
return { kind: "status", action: "queue" };
|
|
22
|
-
}
|
|
23
|
-
if (data === "menu:settings" || data === "status:settings") {
|
|
24
|
-
return { kind: "status", action: "settings" };
|
|
25
|
-
}
|
|
26
|
-
if (data?.startsWith("thinking:set:")) {
|
|
27
|
-
return {
|
|
28
|
-
kind: "thinking:set",
|
|
29
|
-
level: data.slice("thinking:set:".length),
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
if (data?.startsWith("model:")) {
|
|
33
|
-
const [, action, value] = data.split(":");
|
|
34
|
-
if (action === "noop" ||
|
|
35
|
-
action === "scope" ||
|
|
36
|
-
action === "page" ||
|
|
37
|
-
action === "pages" ||
|
|
38
|
-
action === "open" ||
|
|
39
|
-
action === "pick" ||
|
|
40
|
-
action === "pick-selected" ||
|
|
41
|
-
action === "scope-enable" ||
|
|
42
|
-
action === "scope-disable" ||
|
|
43
|
-
action === "scope-toggle") {
|
|
44
|
-
return { kind: "model", action, value };
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return { kind: "ignore" };
|
|
48
|
-
}
|
|
49
13
|
export async function handleTelegramMenuCallbackEntry(callbackQueryId, data, state, deps) {
|
|
50
14
|
if (!data) {
|
|
51
15
|
await deps.answerCallbackQuery(callbackQueryId);
|
|
52
16
|
return;
|
|
53
17
|
}
|
|
54
18
|
if (!state) {
|
|
55
|
-
await deps.answerCallbackQuery(callbackQueryId, "Interactive message expired
|
|
19
|
+
await deps.answerCallbackQuery(callbackQueryId, "Interactive message expired");
|
|
56
20
|
return;
|
|
57
21
|
}
|
|
58
22
|
const handled = (await deps.handleStatusAction()) ||
|
|
@@ -87,38 +51,17 @@ export function createTelegramMenuCallbackHandler(deps) {
|
|
|
87
51
|
return (query, ctx) => handleTelegramMenuCallbackRuntime(query, ctx, deps);
|
|
88
52
|
}
|
|
89
53
|
export function createTelegramMenuCallbackHandlerForContext(deps) {
|
|
54
|
+
const { getActiveToolExecutions, ...ports } = deps;
|
|
90
55
|
return createTelegramMenuCallbackHandler({
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
getThinkingLevel: deps.getThinkingLevel,
|
|
94
|
-
setThinkingLevel: deps.setThinkingLevel,
|
|
95
|
-
updateStatus: deps.updateStatus,
|
|
96
|
-
updateModelMenuMessage: deps.updateModelMenuMessage,
|
|
97
|
-
updateThinkingMenuMessage: deps.updateThinkingMenuMessage,
|
|
98
|
-
updateStatusMessage: deps.updateStatusMessage,
|
|
99
|
-
updateSettingsMenuMessage: deps.updateSettingsMenuMessage,
|
|
100
|
-
answerCallbackQuery: deps.answerCallbackQuery,
|
|
101
|
-
isIdle: deps.isIdle,
|
|
102
|
-
hasAbortHandler: deps.hasAbortHandler,
|
|
103
|
-
hasActiveToolExecutions: () => deps.getActiveToolExecutions() > 0,
|
|
104
|
-
persistScopedModelPatterns: deps.persistScopedModelPatterns,
|
|
105
|
-
setModel: deps.setModel,
|
|
106
|
-
setCurrentModel: deps.setCurrentModel,
|
|
107
|
-
stagePendingModelSwitch: deps.stagePendingModelSwitch,
|
|
108
|
-
restartInterruptedTelegramTurn: deps.restartInterruptedTelegramTurn,
|
|
109
|
-
sectionRegistry: deps.sectionRegistry,
|
|
110
|
-
editInteractiveMessage: deps.editInteractiveMessage,
|
|
111
|
-
sendInteractiveMessage: deps.sendInteractiveMessage,
|
|
112
|
-
sendSectionRichMessage: deps.sendSectionRichMessage,
|
|
113
|
-
enqueueSectionPrompt: deps.enqueueSectionPrompt,
|
|
114
|
-
deleteMessage: deps.deleteMessage,
|
|
56
|
+
...ports,
|
|
57
|
+
hasActiveToolExecutions: () => getActiveToolExecutions() > 0,
|
|
115
58
|
});
|
|
116
59
|
}
|
|
117
60
|
export async function handleTelegramMenuCallbackRuntime(query, ctx, deps) {
|
|
118
61
|
if (query.data === "menu:back") {
|
|
119
62
|
const state = deps.getStoredModelMenuState(query.message?.message_id, query.message?.chat?.id);
|
|
120
63
|
if (!state) {
|
|
121
|
-
await deps.answerCallbackQuery(query.id, "Interactive message expired
|
|
64
|
+
await deps.answerCallbackQuery(query.id, "Interactive message expired");
|
|
122
65
|
return;
|
|
123
66
|
}
|
|
124
67
|
await deps.updateStatusMessage(state, ctx);
|
|
@@ -139,61 +82,37 @@ export async function handleTelegramMenuCallbackRuntime(query, ctx, deps) {
|
|
|
139
82
|
: undefined;
|
|
140
83
|
if (typeof chatId === "number" && typeof messageId === "number") {
|
|
141
84
|
const { token, action, payload } = parsed;
|
|
85
|
+
const sectionDeps = {
|
|
86
|
+
answerCallbackQuery: deps.answerCallbackQuery,
|
|
87
|
+
target,
|
|
88
|
+
editInteractiveMessage: deps.editInteractiveMessage ?? (async () => { }),
|
|
89
|
+
sendInteractiveMessage: deps.sendInteractiveMessage ?? (async () => undefined),
|
|
90
|
+
sendRichMessage: deps.sendSectionRichMessage ??
|
|
91
|
+
(async () => {
|
|
92
|
+
throw new Error("Rich Message delivery is unavailable");
|
|
93
|
+
}),
|
|
94
|
+
enqueuePrompt: deps.enqueueSectionPrompt
|
|
95
|
+
? (prompt) => deps.enqueueSectionPrompt(prompt, ctx, target, query)
|
|
96
|
+
: async () => { },
|
|
97
|
+
deleteMessage: deps.deleteMessage ?? (async () => { }),
|
|
98
|
+
};
|
|
142
99
|
if (action === "open") {
|
|
143
100
|
const state = deps.getStoredModelMenuState(messageId, chatId);
|
|
144
101
|
if (!state) {
|
|
145
|
-
await deps.answerCallbackQuery(query.id, "Interactive message expired
|
|
102
|
+
await deps.answerCallbackQuery(query.id, "Interactive message expired");
|
|
146
103
|
return;
|
|
147
104
|
}
|
|
148
|
-
const handled = await handleTelegramSectionOpen(deps.sectionRegistry, token, chatId, messageId, query.id,
|
|
149
|
-
answerCallbackQuery: deps.answerCallbackQuery,
|
|
150
|
-
target,
|
|
151
|
-
editInteractiveMessage: deps.editInteractiveMessage ?? (async () => { }),
|
|
152
|
-
sendInteractiveMessage: deps.sendInteractiveMessage ?? (async () => undefined),
|
|
153
|
-
sendRichMessage: deps.sendSectionRichMessage ?? (async () => {
|
|
154
|
-
throw new Error("Rich Message delivery is unavailable");
|
|
155
|
-
}),
|
|
156
|
-
enqueuePrompt: deps.enqueueSectionPrompt
|
|
157
|
-
? (prompt) => deps.enqueueSectionPrompt(prompt, ctx, target, query)
|
|
158
|
-
: async () => { },
|
|
159
|
-
deleteMessage: deps.deleteMessage ?? (async () => { }),
|
|
160
|
-
});
|
|
105
|
+
const handled = await handleTelegramSectionOpen(deps.sectionRegistry, token, chatId, messageId, query.id, sectionDeps);
|
|
161
106
|
if (handled)
|
|
162
107
|
return;
|
|
163
108
|
}
|
|
164
109
|
else if (action === "settings") {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
target,
|
|
169
|
-
editInteractiveMessage: deps.editInteractiveMessage ?? (async () => { }),
|
|
170
|
-
sendInteractiveMessage: deps.sendInteractiveMessage ?? (async () => undefined),
|
|
171
|
-
sendRichMessage: deps.sendSectionRichMessage ?? (async () => {
|
|
172
|
-
throw new Error("Rich Message delivery is unavailable");
|
|
173
|
-
}),
|
|
174
|
-
enqueuePrompt: deps.enqueueSectionPrompt
|
|
175
|
-
? (prompt) => deps.enqueueSectionPrompt(prompt, ctx, target, query)
|
|
176
|
-
: async () => { },
|
|
177
|
-
deleteMessage: deps.deleteMessage ?? (async () => { }),
|
|
178
|
-
});
|
|
179
|
-
if (handled)
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
110
|
+
const handled = await handleTelegramSectionSettingsOpen(deps.sectionRegistry, token, chatId, messageId, query.id, sectionDeps);
|
|
111
|
+
if (handled)
|
|
112
|
+
return;
|
|
182
113
|
}
|
|
183
114
|
else {
|
|
184
|
-
const handled = await handleTelegramSectionCallback(deps.sectionRegistry, token, action, payload, chatId, messageId, query.id,
|
|
185
|
-
answerCallbackQuery: deps.answerCallbackQuery,
|
|
186
|
-
target,
|
|
187
|
-
editInteractiveMessage: deps.editInteractiveMessage ?? (async () => { }),
|
|
188
|
-
sendInteractiveMessage: deps.sendInteractiveMessage ?? (async () => undefined),
|
|
189
|
-
sendRichMessage: deps.sendSectionRichMessage ?? (async () => {
|
|
190
|
-
throw new Error("Rich Message delivery is unavailable");
|
|
191
|
-
}),
|
|
192
|
-
enqueuePrompt: deps.enqueueSectionPrompt
|
|
193
|
-
? (prompt) => deps.enqueueSectionPrompt(prompt, ctx, target, query)
|
|
194
|
-
: async () => { },
|
|
195
|
-
deleteMessage: deps.deleteMessage ?? (async () => { }),
|
|
196
|
-
});
|
|
115
|
+
const handled = await handleTelegramSectionCallback(deps.sectionRegistry, token, action, payload, chatId, messageId, query.id, sectionDeps);
|
|
197
116
|
if (handled)
|
|
198
117
|
return;
|
|
199
118
|
}
|
|
@@ -257,67 +176,76 @@ export async function handleTelegramMenuCallbackRuntime(query, ctx, deps) {
|
|
|
257
176
|
answerCallbackQuery: deps.answerCallbackQuery,
|
|
258
177
|
});
|
|
259
178
|
}
|
|
260
|
-
export function createTelegramMenuActionRuntimeWithStateBuilder(deps) {
|
|
261
|
-
return createTelegramMenuActionRuntime({
|
|
262
|
-
getModelMenuState: createTelegramModelMenuStateBuilder({
|
|
263
|
-
runtime: deps.runtime,
|
|
264
|
-
createSettingsManager: deps.createSettingsManager,
|
|
265
|
-
getActiveModel: deps.getActiveModel,
|
|
266
|
-
}),
|
|
267
|
-
getActiveModel: deps.getActiveModel,
|
|
268
|
-
getThinkingLevel: deps.getThinkingLevel,
|
|
269
|
-
getQueueItemCount: deps.getQueueItemCount,
|
|
270
|
-
getPendingCancellationCount: deps.getPendingCancellationCount,
|
|
271
|
-
buildStatusHtml: deps.buildStatusHtml,
|
|
272
|
-
storeModelMenuState: deps.storeModelMenuState,
|
|
273
|
-
isIdle: deps.isIdle,
|
|
274
|
-
canOfferInFlightModelSwitch: deps.canOfferInFlightModelSwitch,
|
|
275
|
-
sendTextReply: deps.sendTextReply,
|
|
276
|
-
editInteractiveMessage: deps.editInteractiveMessage,
|
|
277
|
-
sendInteractiveMessage: deps.sendInteractiveMessage,
|
|
278
|
-
sectionRegistry: deps.sectionRegistry,
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
179
|
export function createTelegramMenuActionRuntime(deps) {
|
|
282
180
|
return {
|
|
283
181
|
updateModelMenuMessage: (state, ctx) => updateTelegramModelMenuMessage(state, deps.getActiveModel(ctx), deps),
|
|
284
182
|
updateThinkingMenuMessage: (state, ctx) => updateTelegramThinkingMenuMessage(state, deps.getActiveModel(ctx), deps.getThinkingLevel(), deps),
|
|
285
183
|
updateStatusMessage: (state, ctx) => updateTelegramStatusMessage(state, deps.buildStatusHtml(ctx), deps.getActiveModel(ctx), deps.getThinkingLevel(), deps, deps.getQueueItemCount?.() ?? 0, deps.sectionRegistry, deps.isVoiceReplyActive?.(), deps.getPendingCancellationCount?.() ?? 0),
|
|
286
|
-
sendStatusMessage: (chatId, replyToMessageId, ctx, threadId) =>
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
184
|
+
sendStatusMessage: (chatId, replyToMessageId, ctx, threadId, options) => {
|
|
185
|
+
const delivery = createTelegramMenuDelivery({ chatId, threadId }, options, deps);
|
|
186
|
+
return openTelegramStatusMenu({
|
|
187
|
+
isIdle: () => deps.isIdle(ctx),
|
|
188
|
+
sendBusyMessage: async () => {
|
|
189
|
+
await deps.sendTextReply(chatId, replyToMessageId, "<b>⏳ Cannot open status while Pi is busy. Send /abort, /next, or /stop.</b>", {
|
|
190
|
+
target: { chatId, threadId },
|
|
191
|
+
parseMode: "HTML",
|
|
192
|
+
...(delivery.assertAuthority
|
|
193
|
+
? { assertAuthority: delivery.assertAuthority }
|
|
194
|
+
: {}),
|
|
195
|
+
});
|
|
196
|
+
},
|
|
197
|
+
getModelMenuState: () => deps.getModelMenuState(chatId, ctx, threadId),
|
|
198
|
+
buildStatusHtml: () => deps.buildStatusHtml(ctx),
|
|
199
|
+
getActiveModel: () => deps.getActiveModel(ctx),
|
|
200
|
+
getThinkingLevel: deps.getThinkingLevel,
|
|
201
|
+
getQueueItemCount: deps.getQueueItemCount,
|
|
202
|
+
sendStatusMenu: (state, statusHtml, activeModel, thinkingLevel, queueItemCount) => sendTelegramStatusMessage(state, statusHtml, activeModel, thinkingLevel, {
|
|
203
|
+
...deps,
|
|
204
|
+
sendInteractiveMessage: delivery.sendInteractiveMessage,
|
|
205
|
+
}, queueItemCount, deps.sectionRegistry, deps.isVoiceReplyActive?.(), deps.getPendingCancellationCount?.() ?? 0),
|
|
206
|
+
storeModelMenuState: delivery.storeModelMenuState,
|
|
207
|
+
});
|
|
208
|
+
},
|
|
209
|
+
openModelMenu: (chatId, replyToMessageId, ctx, threadId, options) => {
|
|
210
|
+
const delivery = createTelegramMenuDelivery({ chatId, threadId }, options, deps);
|
|
211
|
+
const assertAuthority = delivery.assertAuthority;
|
|
212
|
+
return openTelegramModelMenu({
|
|
213
|
+
isIdle: () => deps.isIdle(ctx),
|
|
214
|
+
canOfferInFlightModelSwitch: () => deps.canOfferInFlightModelSwitch(ctx),
|
|
215
|
+
sendBusyMessage: async () => {
|
|
216
|
+
await deps.sendTextReply(chatId, replyToMessageId, "<b>⏳ Cannot switch model while Pi is busy. Send /abort, /next, or /stop.</b>", {
|
|
217
|
+
target: { chatId, threadId },
|
|
218
|
+
parseMode: "HTML",
|
|
219
|
+
...(assertAuthority ? { assertAuthority } : {}),
|
|
220
|
+
});
|
|
221
|
+
},
|
|
222
|
+
sendNoModelsMessage: async () => {
|
|
223
|
+
await deps.sendTextReply(chatId, replyToMessageId, "<b>🚫 No available models with configured auth.</b>", {
|
|
224
|
+
target: { chatId, threadId },
|
|
225
|
+
parseMode: "HTML",
|
|
226
|
+
...(assertAuthority ? { assertAuthority } : {}),
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
getModelMenuState: () => deps.getModelMenuState(chatId, ctx, threadId),
|
|
230
|
+
getActiveModel: () => deps.getActiveModel(ctx),
|
|
231
|
+
sendModelMenu: (state, activeModel) => sendTelegramModelMenuMessage(state, activeModel, {
|
|
232
|
+
...deps,
|
|
233
|
+
sendInteractiveMessage: delivery.sendInteractiveMessage,
|
|
234
|
+
}),
|
|
235
|
+
storeModelMenuState: delivery.storeModelMenuState,
|
|
236
|
+
});
|
|
237
|
+
},
|
|
238
|
+
openThinkingMenu: (chatId, _replyToMessageId, ctx, threadId, options) => {
|
|
239
|
+
const delivery = createTelegramMenuDelivery({ chatId, threadId }, options, deps);
|
|
240
|
+
return openTelegramThinkingMenu({
|
|
241
|
+
getModelMenuState: () => deps.getModelMenuState(chatId, ctx, threadId),
|
|
242
|
+
getActiveModel: () => deps.getActiveModel(ctx),
|
|
243
|
+
getThinkingLevel: deps.getThinkingLevel,
|
|
244
|
+
storeModelMenuState: delivery.storeModelMenuState,
|
|
245
|
+
editInteractiveMessage: deps.editInteractiveMessage,
|
|
246
|
+
sendInteractiveMessage: delivery.sendInteractiveMessage,
|
|
247
|
+
isVoiceReplyActive: deps.isVoiceReplyActive,
|
|
248
|
+
});
|
|
249
|
+
},
|
|
322
250
|
};
|
|
323
251
|
}
|
package/dist/lib/model.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Zones: pi agent model control, telegram controls, queue continuation
|
|
4
4
|
* Owns model identity, thinking levels, scoped resolution, current-model state, and in-flight model switching
|
|
5
5
|
*/
|
|
6
|
-
import type
|
|
6
|
+
import { type PendingTelegramTurn } from "./queue.ts";
|
|
7
7
|
export interface MenuModel {
|
|
8
8
|
provider: string;
|
|
9
9
|
id: string;
|
package/dist/lib/model.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Zones: pi agent model control, telegram controls, queue continuation
|
|
4
4
|
* Owns model identity, thinking levels, scoped resolution, current-model state, and in-flight model switching
|
|
5
5
|
*/
|
|
6
|
+
import { truncateTelegramQueueSummary, } from "./queue.js";
|
|
6
7
|
import { TELEGRAM_PREFIX } from "./turns.js";
|
|
7
8
|
export const THINKING_LEVELS = [
|
|
8
9
|
"off",
|
|
@@ -277,21 +278,6 @@ export function restartTelegramModelSwitchContinuation(state) {
|
|
|
277
278
|
state.abort();
|
|
278
279
|
return true;
|
|
279
280
|
}
|
|
280
|
-
function truncateTelegramModelSwitchStatusSummary(text, maxWords = 4, maxLength = 32) {
|
|
281
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
282
|
-
if (!normalized)
|
|
283
|
-
return "";
|
|
284
|
-
const words = normalized.split(" ");
|
|
285
|
-
let summary = words.slice(0, maxWords).join(" ");
|
|
286
|
-
if (summary.length === 0)
|
|
287
|
-
summary = normalized;
|
|
288
|
-
if (summary.length > maxLength) {
|
|
289
|
-
summary = summary.slice(0, maxLength).trimEnd();
|
|
290
|
-
}
|
|
291
|
-
return summary.length < normalized.length || words.length > maxWords
|
|
292
|
-
? `${summary}…`
|
|
293
|
-
: summary;
|
|
294
|
-
}
|
|
295
281
|
export function buildTelegramModelSwitchContinuationText(telegramPrefix, model, thinkingLevel) {
|
|
296
282
|
const modelLabel = `${model.provider}/${model.id}`;
|
|
297
283
|
const thinkingSuffix = thinkingLevel ? `; thinking: ${thinkingLevel}` : "";
|
|
@@ -299,7 +285,7 @@ export function buildTelegramModelSwitchContinuationText(telegramPrefix, model,
|
|
|
299
285
|
}
|
|
300
286
|
export function buildTelegramModelSwitchContinuationTurn(options) {
|
|
301
287
|
const modelLabel = `${options.selection.model.provider}/${options.selection.model.id}`;
|
|
302
|
-
const statusLabel =
|
|
288
|
+
const statusLabel = truncateTelegramQueueSummary(`continue on ${options.selection.model.id}`, 4, 32);
|
|
303
289
|
return {
|
|
304
290
|
kind: "prompt",
|
|
305
291
|
chatId: options.turn.chatId,
|