omnius 1.0.199 → 1.0.200
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/dist/index.js +754 -13
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23044,6 +23044,13 @@ function deleteRepoFromCache(repo) {
|
|
|
23044
23044
|
}
|
|
23045
23045
|
return removed;
|
|
23046
23046
|
}
|
|
23047
|
+
function deleteCachedModel(repo) {
|
|
23048
|
+
const bytesFreed = deleteRepoFromCache(repo);
|
|
23049
|
+
const meta = readMeta();
|
|
23050
|
+
meta.entries = meta.entries.filter((entry) => entry.repo !== repo);
|
|
23051
|
+
writeMeta(meta);
|
|
23052
|
+
return { repo, bytesFreed };
|
|
23053
|
+
}
|
|
23047
23054
|
function evictModelsToFreeSpace(args) {
|
|
23048
23055
|
const safetyMargin = args.safetyMarginBytes ?? 1 * 1024 ** 3;
|
|
23049
23056
|
const target = args.neededBytes + safetyMargin;
|
|
@@ -534863,6 +534870,7 @@ __export(dist_exports, {
|
|
|
534863
534870
|
createWorktree: () => createWorktree2,
|
|
534864
534871
|
defaultExposureForTool: () => defaultExposureForTool,
|
|
534865
534872
|
defaultExtensionForMime: () => defaultExtensionForMime,
|
|
534873
|
+
deleteCachedModel: () => deleteCachedModel,
|
|
534866
534874
|
deleteMediaModelAdapter: () => deleteMediaModelAdapter,
|
|
534867
534875
|
deleteTodos: () => deleteTodos,
|
|
534868
534876
|
detectCudaDevices: () => detectCudaDevices,
|
|
@@ -630825,9 +630833,14 @@ function buildTelegramCommandMenuItems(scope) {
|
|
|
630825
630833
|
seen.add(cmd.name);
|
|
630826
630834
|
items.push({
|
|
630827
630835
|
label: `/${cmd.name}`,
|
|
630828
|
-
command: `/${cmd.name}`,
|
|
630829
630836
|
description: cmd.signatures[0]?.description ?? signature,
|
|
630830
|
-
adminOnly: scope === "admin"
|
|
630837
|
+
adminOnly: scope === "admin",
|
|
630838
|
+
action: {
|
|
630839
|
+
type: "command_detail",
|
|
630840
|
+
command: `/${cmd.name}`,
|
|
630841
|
+
label: `/${cmd.name}`,
|
|
630842
|
+
description: cmd.signatures.map((sig) => `${sig.signature} - ${sig.description}`).join("\n")
|
|
630843
|
+
}
|
|
630831
630844
|
});
|
|
630832
630845
|
}
|
|
630833
630846
|
return items.sort((a2, b) => a2.label.localeCompare(b.label));
|
|
@@ -630835,10 +630848,18 @@ function buildTelegramCommandMenuItems(scope) {
|
|
|
630835
630848
|
function buildTelegramGenerativeMenuItems(commandName) {
|
|
630836
630849
|
const name10 = commandName.replace(/^\//, "").toLowerCase();
|
|
630837
630850
|
if (!GENERATIVE_COMMANDS.has(name10)) return [];
|
|
630851
|
+
if (name10 === "models") {
|
|
630852
|
+
return [
|
|
630853
|
+
{ label: "CAD models", description: "Browse text-to-CAD adapters.", action: { type: "models", generation: "cad" } },
|
|
630854
|
+
{ label: "3D models", description: "Browse 3D mesh/reconstruction adapters.", action: { type: "models", generation: "model3d" } },
|
|
630855
|
+
{ label: "Model store", command: "/models", description: "Show unified model store status.", action: { type: "command", command: "/models" } }
|
|
630856
|
+
];
|
|
630857
|
+
}
|
|
630838
630858
|
const title = name10[0].toUpperCase() + name10.slice(1);
|
|
630859
|
+
const generation = name10 === "sound" ? "sound" : name10 === "music" ? "music" : name10;
|
|
630839
630860
|
return [
|
|
630840
|
-
{ label: `${title} models`,
|
|
630841
|
-
{ label: `${title} setup`,
|
|
630861
|
+
{ label: `${title} models`, description: `Browse selectable ${name10} models, metadata, cache state, and actions.`, action: { type: "models", generation } },
|
|
630862
|
+
{ label: `${title} setup`, description: `Show setup commands for the ${name10} backend.`, action: { type: "setup_generation", generation } }
|
|
630842
630863
|
];
|
|
630843
630864
|
}
|
|
630844
630865
|
function encodeTelegramCommandMenuCallback(action, value2) {
|
|
@@ -630848,43 +630869,85 @@ function encodeTelegramCommandMenuCallback(action, value2) {
|
|
|
630848
630869
|
function decodeTelegramCommandMenuCallback(data) {
|
|
630849
630870
|
const parts = data.split(":");
|
|
630850
630871
|
if (parts.length !== 3 || parts[0] !== CALLBACK_PREFIX2) return null;
|
|
630851
|
-
const action = parts[1] === "p" ? "page" : parts[1] === "r" ? "run" : parts[1] === "c" ? "close" : null;
|
|
630872
|
+
const action = parts[1] === "p" ? "page" : parts[1] === "r" ? "run" : parts[1] === "c" ? "close" : parts[1] === "b" ? "back" : null;
|
|
630852
630873
|
if (!action) return null;
|
|
630853
630874
|
return { action, value: parts[2] ?? "" };
|
|
630854
630875
|
}
|
|
630876
|
+
function pushTelegramCommandMenuState(state, next) {
|
|
630877
|
+
const crumb = {
|
|
630878
|
+
kind: state.kind,
|
|
630879
|
+
title: state.title,
|
|
630880
|
+
subtitle: state.subtitle,
|
|
630881
|
+
body: state.body,
|
|
630882
|
+
page: state.page,
|
|
630883
|
+
items: state.items
|
|
630884
|
+
};
|
|
630885
|
+
return {
|
|
630886
|
+
...state,
|
|
630887
|
+
kind: next.kind ?? state.kind,
|
|
630888
|
+
title: next.title,
|
|
630889
|
+
subtitle: next.subtitle,
|
|
630890
|
+
body: next.body,
|
|
630891
|
+
page: next.page ?? 0,
|
|
630892
|
+
items: next.items,
|
|
630893
|
+
breadcrumbs: [...state.breadcrumbs ?? [], crumb]
|
|
630894
|
+
};
|
|
630895
|
+
}
|
|
630896
|
+
function popTelegramCommandMenuState(state) {
|
|
630897
|
+
const stack = state.breadcrumbs ?? [];
|
|
630898
|
+
const previous = stack.at(-1);
|
|
630899
|
+
if (!previous) return null;
|
|
630900
|
+
return {
|
|
630901
|
+
...state,
|
|
630902
|
+
kind: previous.kind,
|
|
630903
|
+
title: previous.title,
|
|
630904
|
+
subtitle: previous.subtitle,
|
|
630905
|
+
body: previous.body,
|
|
630906
|
+
page: previous.page,
|
|
630907
|
+
items: previous.items,
|
|
630908
|
+
breadcrumbs: stack.slice(0, -1)
|
|
630909
|
+
};
|
|
630910
|
+
}
|
|
630855
630911
|
function renderTelegramCommandMenu(state) {
|
|
630856
630912
|
const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
|
|
630857
630913
|
const page2 = Math.max(0, Math.min(state.page, totalPages - 1));
|
|
630858
630914
|
const start2 = page2 * PAGE_SIZE2;
|
|
630859
630915
|
const visible = state.items.slice(start2, start2 + PAGE_SIZE2);
|
|
630860
|
-
const title = state.kind === "generative" ? "Generative command" : "Commands";
|
|
630916
|
+
const title = state.title || (state.kind === "generative" ? "Generative command" : state.kind === "models" ? "Models" : "Commands");
|
|
630861
630917
|
const scope = state.scope === "admin" ? "admin" : "public";
|
|
630862
630918
|
const lines = [
|
|
630863
630919
|
`<b>${escapeHTML3(title)}</b>`,
|
|
630864
630920
|
`<i>${escapeHTML3(scope)} scope - page ${page2 + 1}/${totalPages}</i>`,
|
|
630921
|
+
state.subtitle ? escapeHTML3(state.subtitle) : "",
|
|
630922
|
+
state.body ? `<blockquote expandable>${escapeHTML3(state.body)}</blockquote>` : "",
|
|
630865
630923
|
"",
|
|
630866
630924
|
...visible.flatMap((item) => [
|
|
630867
|
-
`<code>${escapeHTML3(item.command)}</code>`,
|
|
630925
|
+
item.command ? `<code>${escapeHTML3(item.command)}</code>` : `<b>${escapeHTML3(item.label)}</b>`,
|
|
630868
630926
|
escapeHTML3(item.description)
|
|
630869
630927
|
])
|
|
630870
|
-
];
|
|
630928
|
+
].filter((line) => line !== "");
|
|
630871
630929
|
const keyboard = visible.map((item, offset) => [{
|
|
630872
630930
|
text: item.label.slice(0, 32),
|
|
630873
630931
|
callback_data: encodeTelegramCommandMenuCallback("run", start2 + offset)
|
|
630874
630932
|
}]);
|
|
630875
630933
|
const nav = [];
|
|
630876
630934
|
nav.push({ text: "Close", callback_data: encodeTelegramCommandMenuCallback("close", 0) });
|
|
630935
|
+
if ((state.breadcrumbs ?? []).length > 0) nav.push({ text: "Back", callback_data: encodeTelegramCommandMenuCallback("back", 0) });
|
|
630877
630936
|
if (page2 > 0) nav.push({ text: "Prev", callback_data: encodeTelegramCommandMenuCallback("page", page2 - 1) });
|
|
630878
630937
|
nav.push({ text: `${page2 + 1}/${totalPages}`, callback_data: encodeTelegramCommandMenuCallback("page", page2) });
|
|
630879
630938
|
if (page2 < totalPages - 1) nav.push({ text: "Next", callback_data: encodeTelegramCommandMenuCallback("page", page2 + 1) });
|
|
630880
630939
|
keyboard.push(nav);
|
|
630881
|
-
return { text: lines.join("\n"), reply_markup: { inline_keyboard: keyboard } };
|
|
630940
|
+
return { text: truncateTelegramMenuText(lines.join("\n")), reply_markup: { inline_keyboard: keyboard } };
|
|
630882
630941
|
}
|
|
630883
630942
|
function handleTelegramCommandMenuCallback(data, state, now = Date.now()) {
|
|
630884
630943
|
const decoded = decodeTelegramCommandMenuCallback(data);
|
|
630885
630944
|
if (!decoded) return null;
|
|
630886
630945
|
if (state.expiresAt <= now) return null;
|
|
630887
630946
|
if (decoded.action === "close") return { close: true };
|
|
630947
|
+
if (decoded.action === "back") {
|
|
630948
|
+
const newState = popTelegramCommandMenuState(state);
|
|
630949
|
+
return newState ? { newState, render: renderTelegramCommandMenu(newState) } : null;
|
|
630950
|
+
}
|
|
630888
630951
|
if (decoded.action === "page") {
|
|
630889
630952
|
const totalPages = Math.max(1, Math.ceil(state.items.length / PAGE_SIZE2));
|
|
630890
630953
|
const page2 = Math.max(0, Math.min(Number.parseInt(decoded.value, 10) || 0, totalPages - 1));
|
|
@@ -630893,21 +630956,28 @@ function handleTelegramCommandMenuCallback(data, state, now = Date.now()) {
|
|
|
630893
630956
|
}
|
|
630894
630957
|
const index = Number.parseInt(decoded.value, 10);
|
|
630895
630958
|
const item = Number.isFinite(index) ? state.items[index] : void 0;
|
|
630896
|
-
|
|
630959
|
+
if (!item) return null;
|
|
630960
|
+
return item.command ? { command: item.command, item } : { item };
|
|
630897
630961
|
}
|
|
630898
630962
|
function escapeHTML3(text) {
|
|
630899
630963
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
630900
630964
|
}
|
|
630965
|
+
function truncateTelegramMenuText(text) {
|
|
630966
|
+
if (text.length <= 3900) return text;
|
|
630967
|
+
return `${text.slice(0, 3820)}
|
|
630968
|
+
|
|
630969
|
+
<i>... menu page clipped; use buttons to narrow this view.</i>`;
|
|
630970
|
+
}
|
|
630901
630971
|
var CALLBACK_PREFIX2, PAGE_SIZE2, TTL_MS, MAX_CALLBACK_DATA_BYTES, GENERATIVE_COMMANDS, TelegramCommandMenuStateStore;
|
|
630902
630972
|
var init_telegram_command_menu = __esm({
|
|
630903
630973
|
"packages/cli/src/tui/telegram-command-menu.ts"() {
|
|
630904
630974
|
"use strict";
|
|
630905
630975
|
init_command_registry();
|
|
630906
630976
|
CALLBACK_PREFIX2 = "ocm";
|
|
630907
|
-
PAGE_SIZE2 =
|
|
630977
|
+
PAGE_SIZE2 = 7;
|
|
630908
630978
|
TTL_MS = 10 * 60 * 1e3;
|
|
630909
630979
|
MAX_CALLBACK_DATA_BYTES = 64;
|
|
630910
|
-
GENERATIVE_COMMANDS = /* @__PURE__ */ new Set(["image", "video", "sound", "music"]);
|
|
630980
|
+
GENERATIVE_COMMANDS = /* @__PURE__ */ new Set(["image", "video", "sound", "music", "models"]);
|
|
630911
630981
|
TelegramCommandMenuStateStore = class {
|
|
630912
630982
|
states = /* @__PURE__ */ new Map();
|
|
630913
630983
|
key(chatId, messageId) {
|
|
@@ -630916,6 +630986,7 @@ var init_telegram_command_menu = __esm({
|
|
|
630916
630986
|
create(input, now = Date.now()) {
|
|
630917
630987
|
return {
|
|
630918
630988
|
...input,
|
|
630989
|
+
breadcrumbs: input.breadcrumbs ?? [],
|
|
630919
630990
|
createdAt: now,
|
|
630920
630991
|
expiresAt: now + TTL_MS
|
|
630921
630992
|
};
|
|
@@ -634367,6 +634438,17 @@ import { join as join140, resolve as resolve53, basename as basename35, relative
|
|
|
634367
634438
|
import { homedir as homedir44 } from "node:os";
|
|
634368
634439
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
634369
634440
|
import { createHash as createHash33, randomBytes as randomBytes25, randomInt } from "node:crypto";
|
|
634441
|
+
function formatModelBytes(bytes) {
|
|
634442
|
+
if (!Number.isFinite(bytes) || bytes <= 0) return "0 B";
|
|
634443
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
634444
|
+
let value2 = bytes;
|
|
634445
|
+
let unit = 0;
|
|
634446
|
+
while (value2 >= 1024 && unit < units.length - 1) {
|
|
634447
|
+
value2 /= 1024;
|
|
634448
|
+
unit++;
|
|
634449
|
+
}
|
|
634450
|
+
return `${value2 >= 10 || unit === 0 ? value2.toFixed(0) : value2.toFixed(1)} ${units[unit]}`;
|
|
634451
|
+
}
|
|
634370
634452
|
function cleanTelegramDecisionNote(value2, maxLength = 260) {
|
|
634371
634453
|
if (typeof value2 !== "string") return void 0;
|
|
634372
634454
|
const clean5 = stripTelegramHiddenThinking(value2).replace(/\s+/g, " ").trim();
|
|
@@ -637055,6 +637137,8 @@ Telegram link integrity contract:
|
|
|
637055
637137
|
statsMenuPruneTimer = null;
|
|
637056
637138
|
/** Telegram-native command and generative command menus */
|
|
637057
637139
|
telegramCommandMenuStates = new TelegramCommandMenuStateStore();
|
|
637140
|
+
/** One-shot Telegram prompt intents created by model-menu "Generate" buttons. */
|
|
637141
|
+
telegramGenerationPromptIntents = /* @__PURE__ */ new Map();
|
|
637058
637142
|
/** Command handler for admin DM slash commands (wired from interactive.ts) */
|
|
637059
637143
|
commandHandler = null;
|
|
637060
637144
|
/** Callback fired after a Telegram user completes the TUI-only admin auth challenge */
|
|
@@ -637992,7 +638076,7 @@ ${message2}`)
|
|
|
637992
638076
|
return;
|
|
637993
638077
|
}
|
|
637994
638078
|
if (msg.guestQueryId || !isAdmin) {
|
|
637995
|
-
const lines = items.slice(0, 24).map((item) => `${item.command} - ${item.description}`);
|
|
638079
|
+
const lines = items.slice(0, 24).map((item) => `${item.command ?? item.label} - ${item.description}`);
|
|
637996
638080
|
const text = ["Available commands:", "", ...lines].join("\n");
|
|
637997
638081
|
if (msg.guestQueryId) {
|
|
637998
638082
|
await this.answerGuestQuery(msg.guestQueryId, text);
|
|
@@ -638008,9 +638092,14 @@ ${message2}`)
|
|
|
638008
638092
|
fromUserId: msg.fromUserId ?? 0,
|
|
638009
638093
|
scope,
|
|
638010
638094
|
kind,
|
|
638095
|
+
title: kind === "generative" ? `/${commandName ?? "models"}` : void 0,
|
|
638096
|
+
subtitle: kind === "generative" ? "Telegram-native menu; buttons render data and tools directly here." : void 0,
|
|
638011
638097
|
page: 0,
|
|
638012
638098
|
items
|
|
638013
638099
|
});
|
|
638100
|
+
await this.sendTelegramCommandMenuState(msg, previewState);
|
|
638101
|
+
}
|
|
638102
|
+
async sendTelegramCommandMenuState(msg, previewState) {
|
|
638014
638103
|
const menu = renderTelegramCommandMenu(previewState);
|
|
638015
638104
|
const sent = await this.apiCall("sendMessage", {
|
|
638016
638105
|
chat_id: msg.chatId,
|
|
@@ -638027,6 +638116,643 @@ ${message2}`)
|
|
|
638027
638116
|
});
|
|
638028
638117
|
}
|
|
638029
638118
|
}
|
|
638119
|
+
async editTelegramCommandMenuState(chatId, messageId, state) {
|
|
638120
|
+
const render2 = renderTelegramCommandMenu(state);
|
|
638121
|
+
this.telegramCommandMenuStates.set(state);
|
|
638122
|
+
await this.apiCall("editMessageText", {
|
|
638123
|
+
chat_id: chatId,
|
|
638124
|
+
message_id: messageId,
|
|
638125
|
+
text: render2.text,
|
|
638126
|
+
parse_mode: "HTML",
|
|
638127
|
+
reply_markup: JSON.stringify(render2.reply_markup)
|
|
638128
|
+
});
|
|
638129
|
+
}
|
|
638130
|
+
telegramGenerationIntentKey(chatId, fromUserId) {
|
|
638131
|
+
return `${String(chatId)}:${fromUserId}`;
|
|
638132
|
+
}
|
|
638133
|
+
pruneTelegramGenerationPromptIntents(now = Date.now()) {
|
|
638134
|
+
for (const [key, intent] of this.telegramGenerationPromptIntents) {
|
|
638135
|
+
if (intent.expiresAt <= now) this.telegramGenerationPromptIntents.delete(key);
|
|
638136
|
+
}
|
|
638137
|
+
}
|
|
638138
|
+
telegramGenerationLabel(generation) {
|
|
638139
|
+
if (generation === "model3d") return "3D model";
|
|
638140
|
+
if (generation === "cad") return "CAD";
|
|
638141
|
+
return generation;
|
|
638142
|
+
}
|
|
638143
|
+
telegramModelCachedBytes(dependencies) {
|
|
638144
|
+
return dependencies.reduce((sum, dep) => sum + measureRepoCacheBytes(dep), 0);
|
|
638145
|
+
}
|
|
638146
|
+
telegramImageModelDescriptors() {
|
|
638147
|
+
return imageGenerationModelPresets().map((preset) => {
|
|
638148
|
+
const dependencies = imagePresetDependencyModels(preset, preset.id);
|
|
638149
|
+
return {
|
|
638150
|
+
generation: "image",
|
|
638151
|
+
id: preset.id,
|
|
638152
|
+
label: preset.label,
|
|
638153
|
+
backend: preset.backend,
|
|
638154
|
+
category: preset.category ?? "Image",
|
|
638155
|
+
sizeClass: preset.sizeClass ?? "",
|
|
638156
|
+
quality: preset.quality ?? preset.note,
|
|
638157
|
+
note: preset.note,
|
|
638158
|
+
install: preset.install,
|
|
638159
|
+
minVramGB: preset.minVramGB,
|
|
638160
|
+
recommendedVramGB: preset.recommendedVramGB,
|
|
638161
|
+
approxDownloadGB: preset.approxDownloadGB,
|
|
638162
|
+
dependencies,
|
|
638163
|
+
cachedBytes: this.telegramModelCachedBytes(dependencies)
|
|
638164
|
+
};
|
|
638165
|
+
});
|
|
638166
|
+
}
|
|
638167
|
+
telegramAudioModelDescriptors(kind) {
|
|
638168
|
+
return audioGenerationModelPresets(kind).map((preset) => {
|
|
638169
|
+
const dependencies = [preset.id];
|
|
638170
|
+
return {
|
|
638171
|
+
generation: kind,
|
|
638172
|
+
id: preset.id,
|
|
638173
|
+
label: preset.label,
|
|
638174
|
+
backend: preset.backend,
|
|
638175
|
+
category: preset.category,
|
|
638176
|
+
sizeClass: preset.sizeClass,
|
|
638177
|
+
quality: preset.quality,
|
|
638178
|
+
note: preset.note,
|
|
638179
|
+
install: preset.install,
|
|
638180
|
+
minVramGB: preset.minVramGB,
|
|
638181
|
+
recommendedVramGB: preset.recommendedVramGB,
|
|
638182
|
+
approxDownloadGB: preset.approxDownloadGB,
|
|
638183
|
+
dependencies,
|
|
638184
|
+
cachedBytes: this.telegramModelCachedBytes(dependencies)
|
|
638185
|
+
};
|
|
638186
|
+
});
|
|
638187
|
+
}
|
|
638188
|
+
telegramVideoModelDescriptors() {
|
|
638189
|
+
return videoGenerationModelPresets().map((preset) => {
|
|
638190
|
+
const dependencies = [preset.id];
|
|
638191
|
+
return {
|
|
638192
|
+
generation: "video",
|
|
638193
|
+
id: preset.id,
|
|
638194
|
+
label: preset.label,
|
|
638195
|
+
backend: preset.backend,
|
|
638196
|
+
category: preset.category,
|
|
638197
|
+
sizeClass: preset.sizeClass,
|
|
638198
|
+
quality: preset.quality,
|
|
638199
|
+
note: preset.note,
|
|
638200
|
+
install: preset.install,
|
|
638201
|
+
minVramGB: preset.minVramGB,
|
|
638202
|
+
recommendedVramGB: preset.recommendedVramGB,
|
|
638203
|
+
approxDownloadGB: preset.approxDownloadGB,
|
|
638204
|
+
dependencies,
|
|
638205
|
+
cachedBytes: this.telegramModelCachedBytes(dependencies),
|
|
638206
|
+
unavailableReason: preset.gated ? "Requires Hugging Face token/license acceptance." : void 0
|
|
638207
|
+
};
|
|
638208
|
+
});
|
|
638209
|
+
}
|
|
638210
|
+
telegramCad3dModelDescriptors(generation) {
|
|
638211
|
+
const modality = generation === "cad" ? "cad" : "3d";
|
|
638212
|
+
return listMediaModelCatalog(modality).map((entry) => {
|
|
638213
|
+
const spec = entry.spec;
|
|
638214
|
+
const dependencies = [spec.repoId];
|
|
638215
|
+
const notes = spec.deployment.notes.join(" ");
|
|
638216
|
+
return {
|
|
638217
|
+
generation,
|
|
638218
|
+
id: spec.id,
|
|
638219
|
+
label: spec.label || spec.repoId,
|
|
638220
|
+
backend: spec.backend,
|
|
638221
|
+
category: `${spec.modality}/${spec.status}`,
|
|
638222
|
+
sizeClass: spec.resources.approxDownloadGB ? `~${spec.resources.approxDownloadGB}GB download` : spec.runner,
|
|
638223
|
+
quality: spec.hf.cardExcerpt || notes || spec.runner,
|
|
638224
|
+
note: notes || spec.deployment.install,
|
|
638225
|
+
install: spec.deployment.install,
|
|
638226
|
+
minVramGB: spec.resources.minVramGB,
|
|
638227
|
+
recommendedVramGB: spec.resources.recommendedVramGB,
|
|
638228
|
+
approxDownloadGB: spec.resources.approxDownloadGB,
|
|
638229
|
+
dependencies,
|
|
638230
|
+
cachedBytes: this.telegramModelCachedBytes(dependencies),
|
|
638231
|
+
unavailableReason: spec.deployment.runtimeCompatible ? void 0 : "Catalog metadata exists, but the runtime adapter is not wired for artifact creation."
|
|
638232
|
+
};
|
|
638233
|
+
});
|
|
638234
|
+
}
|
|
638235
|
+
telegramGenerationModelDescriptors(generation) {
|
|
638236
|
+
if (generation === "image") return this.telegramImageModelDescriptors();
|
|
638237
|
+
if (generation === "sound" || generation === "music") return this.telegramAudioModelDescriptors(generation);
|
|
638238
|
+
if (generation === "video") return this.telegramVideoModelDescriptors();
|
|
638239
|
+
return this.telegramCad3dModelDescriptors(generation);
|
|
638240
|
+
}
|
|
638241
|
+
telegramModelDescriptor(generation, id) {
|
|
638242
|
+
return this.telegramGenerationModelDescriptors(generation).find((model) => model.id === id);
|
|
638243
|
+
}
|
|
638244
|
+
telegramModelMenuItems(generation) {
|
|
638245
|
+
return this.telegramGenerationModelDescriptors(generation).map((model) => {
|
|
638246
|
+
const cached = model.cachedBytes > 0 ? `cached ${formatModelBytes(model.cachedBytes)}` : "not downloaded";
|
|
638247
|
+
const fit3 = model.recommendedVramGB ? `${model.recommendedVramGB}GB VRAM rec` : model.minVramGB ? `${model.minVramGB}GB VRAM min` : "VRAM n/a";
|
|
638248
|
+
return {
|
|
638249
|
+
label: model.label,
|
|
638250
|
+
description: `${model.backend} - ${model.category} - ${fit3} - ${cached}`,
|
|
638251
|
+
action: {
|
|
638252
|
+
type: "model_detail",
|
|
638253
|
+
generation,
|
|
638254
|
+
model: model.id
|
|
638255
|
+
}
|
|
638256
|
+
};
|
|
638257
|
+
});
|
|
638258
|
+
}
|
|
638259
|
+
telegramModelDetailBody(model) {
|
|
638260
|
+
const cached = model.cachedBytes > 0 ? `${formatModelBytes(model.cachedBytes)} cached` : "not downloaded";
|
|
638261
|
+
const deps = model.dependencies.length > 0 ? model.dependencies.join(", ") : model.id;
|
|
638262
|
+
return [
|
|
638263
|
+
`id: ${model.id}`,
|
|
638264
|
+
`backend: ${model.backend}`,
|
|
638265
|
+
`category: ${model.category}`,
|
|
638266
|
+
`size: ${model.sizeClass || "unknown"}`,
|
|
638267
|
+
`download: ${model.approxDownloadGB ? `~${model.approxDownloadGB}GB` : "unknown"}; cache: ${cached}`,
|
|
638268
|
+
`vram: min ${model.minVramGB ?? "?"}GB; recommended ${model.recommendedVramGB ?? "?"}GB`,
|
|
638269
|
+
`dependencies: ${deps}`,
|
|
638270
|
+
model.unavailableReason ? `runtime note: ${model.unavailableReason}` : "",
|
|
638271
|
+
"",
|
|
638272
|
+
`quality: ${model.quality}`,
|
|
638273
|
+
"",
|
|
638274
|
+
`note: ${model.note}`,
|
|
638275
|
+
model.install ? `
|
|
638276
|
+
install/prewarm: ${model.install}` : ""
|
|
638277
|
+
].filter(Boolean).join("\n");
|
|
638278
|
+
}
|
|
638279
|
+
telegramModelDetailItems(model) {
|
|
638280
|
+
return [
|
|
638281
|
+
{
|
|
638282
|
+
label: "Generate",
|
|
638283
|
+
description: "Use this model for the next Telegram message you type.",
|
|
638284
|
+
action: { type: "await_prompt", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
|
|
638285
|
+
},
|
|
638286
|
+
{
|
|
638287
|
+
label: "Load",
|
|
638288
|
+
description: "Download/prewarm or check this model in the generation runtime.",
|
|
638289
|
+
action: { type: "prewarm_model", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
|
|
638290
|
+
},
|
|
638291
|
+
{
|
|
638292
|
+
label: "Delete",
|
|
638293
|
+
description: "Remove cached weights for this model and its adapter/base dependencies.",
|
|
638294
|
+
action: { type: "delete_model", generation: model.generation, model: model.id, backend: model.backend, label: model.label }
|
|
638295
|
+
}
|
|
638296
|
+
];
|
|
638297
|
+
}
|
|
638298
|
+
async replyWithTelegramModelBrowser(msg, isAdmin, generation) {
|
|
638299
|
+
if (!isAdmin) {
|
|
638300
|
+
await this.replyToTelegramMessage(msg, "Model menus require Telegram admin authentication.");
|
|
638301
|
+
return;
|
|
638302
|
+
}
|
|
638303
|
+
const scope = "admin";
|
|
638304
|
+
const title = `${this.telegramGenerationLabel(generation)} models`;
|
|
638305
|
+
const cachedCount = listCachedModels().length;
|
|
638306
|
+
const previewState = this.telegramCommandMenuStates.create({
|
|
638307
|
+
chatId: msg.chatId,
|
|
638308
|
+
messageId: 0,
|
|
638309
|
+
invokerMessageId: msg.messageId,
|
|
638310
|
+
fromUserId: msg.fromUserId ?? 0,
|
|
638311
|
+
scope,
|
|
638312
|
+
kind: "models",
|
|
638313
|
+
title,
|
|
638314
|
+
subtitle: `${cachedCount} cached model record(s). Select a model for metadata, load, delete, or generate.`,
|
|
638315
|
+
page: 0,
|
|
638316
|
+
items: this.telegramModelMenuItems(generation)
|
|
638317
|
+
});
|
|
638318
|
+
await this.sendTelegramCommandMenuState(msg, previewState);
|
|
638319
|
+
}
|
|
638320
|
+
parseTelegramGenerationMenuKind(value2) {
|
|
638321
|
+
const raw = String(value2 ?? "").toLowerCase();
|
|
638322
|
+
if (raw === "image" || raw === "sound" || raw === "music" || raw === "video" || raw === "cad") return raw;
|
|
638323
|
+
if (raw === "model3d" || raw === "3d" || raw === "model") return "model3d";
|
|
638324
|
+
return null;
|
|
638325
|
+
}
|
|
638326
|
+
async handleTelegramCommandMenuAction(callback, state, action) {
|
|
638327
|
+
if (!action) return { handled: false };
|
|
638328
|
+
const chatId = callback.chatId;
|
|
638329
|
+
const messageId = callback.messageId;
|
|
638330
|
+
if (!chatId || !messageId) return { handled: true, answerText: "Cannot identify menu message.", alert: true };
|
|
638331
|
+
if (action.type === "command_detail") {
|
|
638332
|
+
const command = typeof action.command === "string" ? action.command : "";
|
|
638333
|
+
if (!command) return { handled: true, answerText: "Command metadata is missing.", alert: true };
|
|
638334
|
+
const body = [
|
|
638335
|
+
`command: ${command}`,
|
|
638336
|
+
"",
|
|
638337
|
+
typeof action.description === "string" ? action.description : "No command details available."
|
|
638338
|
+
].join("\n");
|
|
638339
|
+
const nextState = pushTelegramCommandMenuState(state, {
|
|
638340
|
+
kind: "detail",
|
|
638341
|
+
title: command,
|
|
638342
|
+
subtitle: "Telegram command",
|
|
638343
|
+
body,
|
|
638344
|
+
items: [{
|
|
638345
|
+
label: "Run",
|
|
638346
|
+
command,
|
|
638347
|
+
description: `Execute ${command}.`,
|
|
638348
|
+
action: { type: "command", command }
|
|
638349
|
+
}]
|
|
638350
|
+
});
|
|
638351
|
+
await this.editTelegramCommandMenuState(chatId, messageId, nextState);
|
|
638352
|
+
return { handled: true };
|
|
638353
|
+
}
|
|
638354
|
+
if (action.type === "models") {
|
|
638355
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638356
|
+
if (!generation) return { handled: true, answerText: "Unknown model menu.", alert: true };
|
|
638357
|
+
const nextState = pushTelegramCommandMenuState(state, {
|
|
638358
|
+
kind: "models",
|
|
638359
|
+
title: `${this.telegramGenerationLabel(generation)} models`,
|
|
638360
|
+
subtitle: "Select a model for metadata, load, delete, or generate.",
|
|
638361
|
+
items: this.telegramModelMenuItems(generation)
|
|
638362
|
+
});
|
|
638363
|
+
await this.editTelegramCommandMenuState(chatId, messageId, nextState);
|
|
638364
|
+
return { handled: true };
|
|
638365
|
+
}
|
|
638366
|
+
if (action.type === "setup_generation") {
|
|
638367
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638368
|
+
if (!generation) return { handled: true, answerText: "Unknown setup menu.", alert: true };
|
|
638369
|
+
await this.answerCallbackQuery(callback.id, `Preparing ${this.telegramGenerationLabel(generation)} setup...`).catch(() => false);
|
|
638370
|
+
await this.replyWithTelegramGenerationSetup({
|
|
638371
|
+
chatId,
|
|
638372
|
+
text: "",
|
|
638373
|
+
username: callback.username,
|
|
638374
|
+
firstName: callback.firstName,
|
|
638375
|
+
messageId,
|
|
638376
|
+
fromUserId: callback.fromUserId,
|
|
638377
|
+
chatType: "private"
|
|
638378
|
+
}, generation);
|
|
638379
|
+
return { handled: true, answered: true };
|
|
638380
|
+
}
|
|
638381
|
+
if (action.type === "model_detail") {
|
|
638382
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638383
|
+
const modelId = typeof action.model === "string" ? action.model : "";
|
|
638384
|
+
const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
|
|
638385
|
+
if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
|
|
638386
|
+
const nextState = pushTelegramCommandMenuState(state, {
|
|
638387
|
+
kind: "detail",
|
|
638388
|
+
title: descriptor.label,
|
|
638389
|
+
subtitle: `${this.telegramGenerationLabel(generation)} model`,
|
|
638390
|
+
body: this.telegramModelDetailBody(descriptor),
|
|
638391
|
+
items: this.telegramModelDetailItems(descriptor)
|
|
638392
|
+
});
|
|
638393
|
+
await this.editTelegramCommandMenuState(chatId, messageId, nextState);
|
|
638394
|
+
return { handled: true };
|
|
638395
|
+
}
|
|
638396
|
+
if (action.type === "await_prompt") {
|
|
638397
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638398
|
+
const modelId = typeof action.model === "string" ? action.model : "";
|
|
638399
|
+
const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
|
|
638400
|
+
if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
|
|
638401
|
+
const now = Date.now();
|
|
638402
|
+
this.pruneTelegramGenerationPromptIntents(now);
|
|
638403
|
+
this.telegramGenerationPromptIntents.set(this.telegramGenerationIntentKey(chatId, callback.fromUserId), {
|
|
638404
|
+
chatId,
|
|
638405
|
+
chatType: "private",
|
|
638406
|
+
fromUserId: callback.fromUserId,
|
|
638407
|
+
username: callback.username,
|
|
638408
|
+
generation,
|
|
638409
|
+
model: descriptor.id,
|
|
638410
|
+
backend: descriptor.backend,
|
|
638411
|
+
label: descriptor.label,
|
|
638412
|
+
createdAt: now,
|
|
638413
|
+
expiresAt: now + 15 * 6e4,
|
|
638414
|
+
menuMessageId: messageId
|
|
638415
|
+
});
|
|
638416
|
+
const nextState = {
|
|
638417
|
+
...state,
|
|
638418
|
+
subtitle: "Waiting for your next Telegram message.",
|
|
638419
|
+
body: [
|
|
638420
|
+
`Selected: ${descriptor.label}`,
|
|
638421
|
+
`Model: ${descriptor.id}`,
|
|
638422
|
+
"",
|
|
638423
|
+
`Send the prompt you want to generate. Omnius will expand it first, then run the ${this.telegramGenerationLabel(generation)} pipeline with this model.`,
|
|
638424
|
+
"Send /cancel to clear this pending generation."
|
|
638425
|
+
].join("\n")
|
|
638426
|
+
};
|
|
638427
|
+
await this.editTelegramCommandMenuState(chatId, messageId, nextState);
|
|
638428
|
+
return { handled: true, answerText: "Send the prompt as your next Telegram message." };
|
|
638429
|
+
}
|
|
638430
|
+
if (action.type === "prewarm_model") {
|
|
638431
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638432
|
+
const modelId = typeof action.model === "string" ? action.model : "";
|
|
638433
|
+
const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
|
|
638434
|
+
if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
|
|
638435
|
+
await this.answerCallbackQuery(callback.id, `Loading ${descriptor.label}...`).catch(() => false);
|
|
638436
|
+
await this.runTelegramGenerationPrewarm(chatId, descriptor);
|
|
638437
|
+
return { handled: true, answered: true };
|
|
638438
|
+
}
|
|
638439
|
+
if (action.type === "delete_model") {
|
|
638440
|
+
const generation = this.parseTelegramGenerationMenuKind(action.generation);
|
|
638441
|
+
const modelId = typeof action.model === "string" ? action.model : "";
|
|
638442
|
+
const descriptor = generation ? this.telegramModelDescriptor(generation, modelId) : void 0;
|
|
638443
|
+
if (!generation || !descriptor) return { handled: true, answerText: "Model metadata is no longer available.", alert: true };
|
|
638444
|
+
const message2 = await this.deleteTelegramGenerationModelWeights(descriptor);
|
|
638445
|
+
await this.sendMessageHTML(chatId, convertMarkdownToTelegramHTML(message2));
|
|
638446
|
+
return { handled: true, answerText: "Delete complete." };
|
|
638447
|
+
}
|
|
638448
|
+
return { handled: false };
|
|
638449
|
+
}
|
|
638450
|
+
async deleteTelegramGenerationModelWeights(model) {
|
|
638451
|
+
if (model.backend === "ollama" || model.id.startsWith("x/")) {
|
|
638452
|
+
const base3 = String(this.agentConfig?.backendUrl || "http://localhost:11434").replace(/\/v1\/?$/, "").replace(/\/$/, "");
|
|
638453
|
+
const resp = await fetch(`${base3}/api/delete`, {
|
|
638454
|
+
method: "DELETE",
|
|
638455
|
+
headers: { "Content-Type": "application/json" },
|
|
638456
|
+
body: JSON.stringify({ name: model.id }),
|
|
638457
|
+
signal: AbortSignal.timeout(3e4)
|
|
638458
|
+
}).catch((err) => {
|
|
638459
|
+
throw new Error(`Ollama delete failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
638460
|
+
});
|
|
638461
|
+
if (resp.status === 404) return `No Ollama weights found for ${model.id}.`;
|
|
638462
|
+
if (!resp.ok) {
|
|
638463
|
+
const text = await resp.text().catch(() => "");
|
|
638464
|
+
throw new Error(`Ollama delete failed for ${model.id}: HTTP ${resp.status}${text ? ` - ${text.slice(0, 300)}` : ""}`);
|
|
638465
|
+
}
|
|
638466
|
+
return `Deleted Ollama weights for ${model.id}.`;
|
|
638467
|
+
}
|
|
638468
|
+
const results = model.dependencies.map((repo) => deleteCachedModel(repo));
|
|
638469
|
+
const freed = results.reduce((sum, item) => sum + item.bytesFreed, 0);
|
|
638470
|
+
const lines = results.map((item) => `- ${item.repo}: ${item.bytesFreed > 0 ? formatModelBytes(item.bytesFreed) : "not cached"}`);
|
|
638471
|
+
return [`Deleted cached model weights for ${model.label}.`, `Freed: ${formatModelBytes(freed)}`, ...lines].join("\n");
|
|
638472
|
+
}
|
|
638473
|
+
telegramCreativeRootForChat(chatId) {
|
|
638474
|
+
return telegramCreativeWorkspaceRoot(this.repoRoot || process.cwd(), chatId);
|
|
638475
|
+
}
|
|
638476
|
+
buildTelegramGenerationTool(root, model) {
|
|
638477
|
+
if (model.generation === "image") {
|
|
638478
|
+
return {
|
|
638479
|
+
tool: new ImageGenerateTool(root, this.agentConfig?.backendUrl, {
|
|
638480
|
+
model: model.id,
|
|
638481
|
+
backend: model.backend
|
|
638482
|
+
}),
|
|
638483
|
+
args: { model: model.id, backend: model.backend }
|
|
638484
|
+
};
|
|
638485
|
+
}
|
|
638486
|
+
if (model.generation === "sound" || model.generation === "music") {
|
|
638487
|
+
return {
|
|
638488
|
+
tool: new AudioGenerateTool(root, model.generation === "music" ? { musicModel: model.id, musicBackend: model.backend } : { soundModel: model.id, soundBackend: model.backend }),
|
|
638489
|
+
args: { kind: model.generation, model: model.id, backend: model.backend }
|
|
638490
|
+
};
|
|
638491
|
+
}
|
|
638492
|
+
if (model.generation === "video") {
|
|
638493
|
+
return {
|
|
638494
|
+
tool: new VideoGenerateTool(root, {
|
|
638495
|
+
model: model.id,
|
|
638496
|
+
backend: model.backend,
|
|
638497
|
+
defaultKind: "t2v"
|
|
638498
|
+
}),
|
|
638499
|
+
args: { model: model.id, backend: model.backend, kind: "t2v" }
|
|
638500
|
+
};
|
|
638501
|
+
}
|
|
638502
|
+
const kind = model.generation === "cad" ? "cad" : "3d";
|
|
638503
|
+
return {
|
|
638504
|
+
tool: new ModelGenerateTool(root, kind === "cad" ? { cadModel: model.id, cadBackend: model.backend } : { model3dModel: model.id, model3dBackend: model.backend }),
|
|
638505
|
+
args: { kind, model: model.id, backend: model.backend }
|
|
638506
|
+
};
|
|
638507
|
+
}
|
|
638508
|
+
attachTelegramGenerationProgress(chatId, messageId, heading, model, tool) {
|
|
638509
|
+
if (!messageId) return;
|
|
638510
|
+
const setProgress = tool.setProgressCallback;
|
|
638511
|
+
if (typeof setProgress !== "function") return;
|
|
638512
|
+
let lastEdit = 0;
|
|
638513
|
+
setProgress.call(tool, (event) => {
|
|
638514
|
+
const now = Date.now();
|
|
638515
|
+
if (now - lastEdit < 2500 && event.percent === void 0) return;
|
|
638516
|
+
lastEdit = now;
|
|
638517
|
+
const percent = typeof event.percent === "number" ? ` ${Math.round(event.percent)}%` : "";
|
|
638518
|
+
const elapsed = typeof event.elapsedMs === "number" ? `
|
|
638519
|
+
Elapsed: ${Math.round(event.elapsedMs / 1e3)}s` : "";
|
|
638520
|
+
const html = [
|
|
638521
|
+
`<b>${escapeTelegramHTML(heading)}</b>`,
|
|
638522
|
+
`Model: <code>${escapeTelegramHTML(model.id)}</code>`,
|
|
638523
|
+
`Stage: <code>${escapeTelegramHTML(String(event.stage || "process"))}</code>${percent}`,
|
|
638524
|
+
escapeTelegramHTML(String(event.message || "")),
|
|
638525
|
+
elapsed
|
|
638526
|
+
].filter(Boolean).join("\n");
|
|
638527
|
+
void this.editLiveMessage(chatId, messageId, html).catch(() => false);
|
|
638528
|
+
});
|
|
638529
|
+
}
|
|
638530
|
+
async runTelegramGenerationPrewarm(chatId, model) {
|
|
638531
|
+
const root = this.telegramCreativeRootForChat(chatId);
|
|
638532
|
+
const { tool, args } = this.buildTelegramGenerationTool(root, model);
|
|
638533
|
+
const liveId = await this.sendMessageHTML(
|
|
638534
|
+
chatId,
|
|
638535
|
+
`<b>Loading ${escapeTelegramHTML(model.label)}</b>
|
|
638536
|
+
Model: <code>${escapeTelegramHTML(model.id)}</code>`
|
|
638537
|
+
);
|
|
638538
|
+
this.attachTelegramGenerationProgress(chatId, liveId, `Loading ${model.label}`, model, tool);
|
|
638539
|
+
const action = model.generation === "model3d" || model.generation === "cad" ? "check" : "prewarm";
|
|
638540
|
+
const result = await tool.execute({ ...args, action });
|
|
638541
|
+
const html = result.success ? `<b>Model load/check complete</b>
|
|
638542
|
+
<blockquote expandable>${escapeTelegramHTML(result.output || "Ready.")}</blockquote>` : `<b>Model load/check failed</b>
|
|
638543
|
+
<blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`;
|
|
638544
|
+
if (liveId) await this.editLiveMessage(chatId, liveId, html).catch(() => false);
|
|
638545
|
+
else await this.sendMessageHTML(chatId, html);
|
|
638546
|
+
}
|
|
638547
|
+
async expandTelegramGenerationPrompt(intent, prompt, modelId = intent.model, backend = intent.backend ?? "auto") {
|
|
638548
|
+
const raw = prompt.trim();
|
|
638549
|
+
if (!raw || !this.agentConfig) return raw;
|
|
638550
|
+
try {
|
|
638551
|
+
const llm = new OllamaAgenticBackend(
|
|
638552
|
+
this.agentConfig.backendUrl,
|
|
638553
|
+
this.agentConfig.model,
|
|
638554
|
+
this.agentConfig.apiKey
|
|
638555
|
+
);
|
|
638556
|
+
const system = [
|
|
638557
|
+
"You rewrite a user's short media-generation request into a stronger production prompt.",
|
|
638558
|
+
"Preserve the user's subject and intent. Add concrete sensory, compositional, timing, material, and style details only where useful.",
|
|
638559
|
+
"Do not add policy commentary, labels, quotes, or explanation. Output only the expanded prompt."
|
|
638560
|
+
].join(" ");
|
|
638561
|
+
const user = [
|
|
638562
|
+
`Generation type: ${intent.generation}`,
|
|
638563
|
+
`Target model: ${modelId}`,
|
|
638564
|
+
`Backend: ${backend}`,
|
|
638565
|
+
"",
|
|
638566
|
+
"User prompt:",
|
|
638567
|
+
raw
|
|
638568
|
+
].join("\n");
|
|
638569
|
+
const result = await this.telegramObservableInference(
|
|
638570
|
+
llm,
|
|
638571
|
+
telegramThinkSuppressedRequest({
|
|
638572
|
+
messages: [
|
|
638573
|
+
{ role: "system", content: system },
|
|
638574
|
+
{ role: "user", content: user }
|
|
638575
|
+
],
|
|
638576
|
+
tools: [],
|
|
638577
|
+
temperature: 0.4,
|
|
638578
|
+
maxTokens: 700,
|
|
638579
|
+
timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 3e4)
|
|
638580
|
+
}),
|
|
638581
|
+
"chat-fast-path",
|
|
638582
|
+
`generation-prompt:${String(intent.chatId)}:${intent.fromUserId}`
|
|
638583
|
+
);
|
|
638584
|
+
const text = result.choices[0]?.message?.content;
|
|
638585
|
+
if (typeof text !== "string") return raw;
|
|
638586
|
+
const cleaned = text.replace(/^["'`]+|["'`]+$/g, "").replace(/^(?:expanded prompt|prompt|output)\s*:\s*/i, "").trim();
|
|
638587
|
+
return cleaned || raw;
|
|
638588
|
+
} catch {
|
|
638589
|
+
return raw;
|
|
638590
|
+
}
|
|
638591
|
+
}
|
|
638592
|
+
installTelegramPromptExpander(tool, intent) {
|
|
638593
|
+
const setExpander = tool.setPromptExpander;
|
|
638594
|
+
if (typeof setExpander !== "function") return;
|
|
638595
|
+
setExpander.call(tool, async (ctx3) => this.expandTelegramGenerationPrompt(intent, ctx3.originalPrompt, ctx3.model, ctx3.backend));
|
|
638596
|
+
}
|
|
638597
|
+
async sendTelegramGenerationArtifacts(msg, root, result) {
|
|
638598
|
+
const paths = /* @__PURE__ */ new Set();
|
|
638599
|
+
for (const path12 of result.mutatedFiles ?? []) {
|
|
638600
|
+
if (typeof path12 === "string" && path12.trim()) paths.add(resolve53(path12));
|
|
638601
|
+
}
|
|
638602
|
+
for (const path12 of collectGeneratedArtifactPathsFromText(result.output || "", root)) {
|
|
638603
|
+
paths.add(resolve53(path12));
|
|
638604
|
+
}
|
|
638605
|
+
let sent = 0;
|
|
638606
|
+
for (const path12 of paths) {
|
|
638607
|
+
if (!existsSync127(path12) || !statSync46(path12).isFile()) continue;
|
|
638608
|
+
const kind = classifyMedia(path12) ?? "document";
|
|
638609
|
+
const messageId = await this.sendMediaReference(msg.chatId, {
|
|
638610
|
+
original: path12,
|
|
638611
|
+
value: path12,
|
|
638612
|
+
kind,
|
|
638613
|
+
source: "file",
|
|
638614
|
+
audioAsVoice: kind === "voice"
|
|
638615
|
+
}, {
|
|
638616
|
+
replyToMessageId: msg.messageId
|
|
638617
|
+
}).catch(() => null);
|
|
638618
|
+
if (messageId !== null) sent++;
|
|
638619
|
+
}
|
|
638620
|
+
return sent;
|
|
638621
|
+
}
|
|
638622
|
+
async executeTelegramGenerationPrompt(msg, intent) {
|
|
638623
|
+
const descriptor = this.telegramModelDescriptor(intent.generation, intent.model) ?? {
|
|
638624
|
+
generation: intent.generation,
|
|
638625
|
+
id: intent.model,
|
|
638626
|
+
label: intent.label,
|
|
638627
|
+
backend: intent.backend || "auto",
|
|
638628
|
+
category: "",
|
|
638629
|
+
sizeClass: "",
|
|
638630
|
+
quality: "",
|
|
638631
|
+
note: "",
|
|
638632
|
+
cachedBytes: 0,
|
|
638633
|
+
dependencies: [intent.model]
|
|
638634
|
+
};
|
|
638635
|
+
const root = this.telegramCreativeRootForChat(msg.chatId);
|
|
638636
|
+
const { tool, args } = this.buildTelegramGenerationTool(root, descriptor);
|
|
638637
|
+
this.installTelegramPromptExpander(tool, intent);
|
|
638638
|
+
const liveId = await this.sendMessageHTML(
|
|
638639
|
+
msg.chatId,
|
|
638640
|
+
[
|
|
638641
|
+
`<b>${escapeTelegramHTML(this.telegramGenerationLabel(intent.generation))} generation</b>`,
|
|
638642
|
+
`Model: <code>${escapeTelegramHTML(intent.model)}</code>`,
|
|
638643
|
+
"Expanding prompt and preparing runtime..."
|
|
638644
|
+
].join("\n"),
|
|
638645
|
+
msg.messageId
|
|
638646
|
+
);
|
|
638647
|
+
this.attachTelegramGenerationProgress(msg.chatId, liveId, `${this.telegramGenerationLabel(intent.generation)} generation`, descriptor, tool);
|
|
638648
|
+
const rawPrompt = msg.text.trim();
|
|
638649
|
+
const prompt = intent.generation === "image" || intent.generation === "video" ? rawPrompt : await this.expandTelegramGenerationPrompt(intent, rawPrompt, descriptor.id, descriptor.backend);
|
|
638650
|
+
const result = await tool.execute({
|
|
638651
|
+
...args,
|
|
638652
|
+
action: "generate",
|
|
638653
|
+
prompt,
|
|
638654
|
+
expand_prompt: true
|
|
638655
|
+
});
|
|
638656
|
+
const artifactCount = result.success ? await this.sendTelegramGenerationArtifacts(msg, root, result) : 0;
|
|
638657
|
+
const summary = result.success ? [
|
|
638658
|
+
`<b>Generation complete</b>`,
|
|
638659
|
+
artifactCount > 0 ? `Sent ${artifactCount} artifact${artifactCount === 1 ? "" : "s"}.` : "No artifact file was detected in the tool result.",
|
|
638660
|
+
`<blockquote expandable>${escapeTelegramHTML(result.output || result.llmContent || "Done.")}</blockquote>`
|
|
638661
|
+
].join("\n") : [
|
|
638662
|
+
`<b>Generation failed</b>`,
|
|
638663
|
+
`<blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`
|
|
638664
|
+
].join("\n");
|
|
638665
|
+
if (liveId) await this.editLiveMessage(msg.chatId, liveId, summary).catch(() => false);
|
|
638666
|
+
else await this.sendMessageHTML(msg.chatId, summary, msg.messageId);
|
|
638667
|
+
}
|
|
638668
|
+
async maybeHandleTelegramGenerationPrompt(msg) {
|
|
638669
|
+
this.pruneTelegramGenerationPromptIntents();
|
|
638670
|
+
const key = this.telegramGenerationIntentKey(msg.chatId, msg.fromUserId);
|
|
638671
|
+
const intent = this.telegramGenerationPromptIntents.get(key);
|
|
638672
|
+
if (!intent) return false;
|
|
638673
|
+
if (msg.text.trim().toLowerCase() === "/cancel") {
|
|
638674
|
+
this.telegramGenerationPromptIntents.delete(key);
|
|
638675
|
+
await this.replyToTelegramMessage(msg, "Pending generation cleared.");
|
|
638676
|
+
return true;
|
|
638677
|
+
}
|
|
638678
|
+
if (msg.text.trim().startsWith("/")) return false;
|
|
638679
|
+
this.telegramGenerationPromptIntents.delete(key);
|
|
638680
|
+
await this.executeTelegramGenerationPrompt(msg, intent);
|
|
638681
|
+
return true;
|
|
638682
|
+
}
|
|
638683
|
+
telegramSlashGenerationKind(name10) {
|
|
638684
|
+
if (name10 === "image") return "image";
|
|
638685
|
+
if (name10 === "sound") return "sound";
|
|
638686
|
+
if (name10 === "music") return "music";
|
|
638687
|
+
if (name10 === "video") return "video";
|
|
638688
|
+
return null;
|
|
638689
|
+
}
|
|
638690
|
+
async replyWithTelegramGenerationSetup(msg, generation) {
|
|
638691
|
+
const root = this.telegramCreativeRootForChat(msg.chatId);
|
|
638692
|
+
const settings = resolveSettings(this.repoRoot || process.cwd());
|
|
638693
|
+
let tool;
|
|
638694
|
+
let args;
|
|
638695
|
+
if (generation === "image") {
|
|
638696
|
+
tool = new ImageGenerateTool(root, this.agentConfig?.backendUrl, this.imageGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
|
|
638697
|
+
args = { action: "setup", model: settings.imageModel, backend: settings.imageBackend };
|
|
638698
|
+
} else if (generation === "sound" || generation === "music") {
|
|
638699
|
+
tool = new AudioGenerateTool(root, this.audioGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
|
|
638700
|
+
args = {
|
|
638701
|
+
action: "setup",
|
|
638702
|
+
kind: generation,
|
|
638703
|
+
model: generation === "music" ? settings.musicModel : settings.soundModel,
|
|
638704
|
+
backend: generation === "music" ? settings.musicBackend : settings.soundBackend
|
|
638705
|
+
};
|
|
638706
|
+
} else if (generation === "video") {
|
|
638707
|
+
tool = new VideoGenerateTool(root, this.videoGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
|
|
638708
|
+
args = { action: "setup", model: settings.videoModel, backend: settings.videoBackend };
|
|
638709
|
+
} else {
|
|
638710
|
+
tool = new ModelGenerateTool(root, this.modelGenerationDefaultsForRepo(this.repoRoot || process.cwd()));
|
|
638711
|
+
args = { action: "list_models", kind: generation === "cad" ? "cad" : "3d" };
|
|
638712
|
+
}
|
|
638713
|
+
const result = await tool.execute(args);
|
|
638714
|
+
const html = result.success ? `<b>${escapeTelegramHTML(this.telegramGenerationLabel(generation))} setup</b>
|
|
638715
|
+
<blockquote expandable>${escapeTelegramHTML(result.output || "No setup output.")}</blockquote>` : `<b>${escapeTelegramHTML(this.telegramGenerationLabel(generation))} setup failed</b>
|
|
638716
|
+
<blockquote expandable>${escapeTelegramHTML(result.error || result.output || "Unknown failure.")}</blockquote>`;
|
|
638717
|
+
await this.replyToTelegramMessage(msg, html, { html: true });
|
|
638718
|
+
}
|
|
638719
|
+
async handleTelegramGenerationSlashCommand(msg, isAdmin, normalizedCommandText) {
|
|
638720
|
+
const trimmed = normalizedCommandText.trim();
|
|
638721
|
+
if (!trimmed.startsWith("/")) return false;
|
|
638722
|
+
const [rawName = "", rawSub = ""] = trimmed.split(/\s+/);
|
|
638723
|
+
const name10 = rawName.slice(1).split("@")[0]?.toLowerCase() ?? "";
|
|
638724
|
+
const sub = rawSub.toLowerCase();
|
|
638725
|
+
if (name10 === "models") {
|
|
638726
|
+
if (!sub) {
|
|
638727
|
+
await this.replyWithTelegramCommandMenu(msg, isAdmin, "generative", "models");
|
|
638728
|
+
return true;
|
|
638729
|
+
}
|
|
638730
|
+
if (sub === "3d" || sub === "cad") {
|
|
638731
|
+
await this.replyWithTelegramModelBrowser(msg, isAdmin, sub === "cad" ? "cad" : "model3d");
|
|
638732
|
+
return true;
|
|
638733
|
+
}
|
|
638734
|
+
return false;
|
|
638735
|
+
}
|
|
638736
|
+
const generation = this.telegramSlashGenerationKind(name10);
|
|
638737
|
+
if (!generation) return false;
|
|
638738
|
+
if (!sub) {
|
|
638739
|
+
await this.replyWithTelegramCommandMenu(msg, isAdmin, "generative", name10);
|
|
638740
|
+
return true;
|
|
638741
|
+
}
|
|
638742
|
+
if (sub === "list" || sub === "models" || sub === "menu") {
|
|
638743
|
+
await this.replyWithTelegramModelBrowser(msg, isAdmin, generation);
|
|
638744
|
+
return true;
|
|
638745
|
+
}
|
|
638746
|
+
if (sub === "setup") {
|
|
638747
|
+
if (!isAdmin) {
|
|
638748
|
+
await this.replyToTelegramMessage(msg, "Generation setup requires Telegram admin authentication.");
|
|
638749
|
+
return true;
|
|
638750
|
+
}
|
|
638751
|
+
await this.replyWithTelegramGenerationSetup(msg, generation);
|
|
638752
|
+
return true;
|
|
638753
|
+
}
|
|
638754
|
+
return false;
|
|
638755
|
+
}
|
|
638030
638756
|
collectSessionMetricsSnapshot() {
|
|
638031
638757
|
if (this._metricsProvider) {
|
|
638032
638758
|
try {
|
|
@@ -643619,6 +644345,9 @@ ${summary}` : ""
|
|
|
643619
644345
|
return;
|
|
643620
644346
|
}
|
|
643621
644347
|
const isAdmin = this.isAdminUser(msg);
|
|
644348
|
+
if (await this.maybeHandleTelegramGenerationPrompt(msg)) {
|
|
644349
|
+
return;
|
|
644350
|
+
}
|
|
643622
644351
|
if (msg.text.trim().startsWith("/") && this.isTelegramCommandsMenuCommand(normalizedCommandText)) {
|
|
643623
644352
|
await this.replyWithTelegramCommandMenu(msg, isAdmin, "commands");
|
|
643624
644353
|
return;
|
|
@@ -643632,6 +644361,9 @@ ${summary}` : ""
|
|
|
643632
644361
|
return;
|
|
643633
644362
|
}
|
|
643634
644363
|
const telegramSlash = this.telegramSlashName(normalizedCommandText);
|
|
644364
|
+
if (msg.text.trim().startsWith("/") && await this.handleTelegramGenerationSlashCommand(msg, isAdmin, normalizedCommandText)) {
|
|
644365
|
+
return;
|
|
644366
|
+
}
|
|
643635
644367
|
if (msg.text.trim().startsWith("/") && TELEGRAM_REFLECTION_SLASH_COMMANDS.has(telegramSlash)) {
|
|
643636
644368
|
await this.handleTelegramReflectionSlash(msg, normalizedCommandText);
|
|
643637
644369
|
return;
|
|
@@ -646495,6 +647227,15 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
646495
647227
|
});
|
|
646496
647228
|
return;
|
|
646497
647229
|
}
|
|
647230
|
+
if (result.item?.action && result.item.action.type !== "command") {
|
|
647231
|
+
const actionResult = await this.handleTelegramCommandMenuAction(callback, menuState, result.item.action);
|
|
647232
|
+
if (actionResult.handled) {
|
|
647233
|
+
if (actionResult.answered) answered = true;
|
|
647234
|
+
if (actionResult.answerText) answerText2 = actionResult.answerText;
|
|
647235
|
+
if (actionResult.alert) alert2 = true;
|
|
647236
|
+
return;
|
|
647237
|
+
}
|
|
647238
|
+
}
|
|
646498
647239
|
if (result.command) {
|
|
646499
647240
|
if (!this.commandHandler) {
|
|
646500
647241
|
answerText2 = "No command handler is available.";
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.200",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.200",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED