omnius 1.0.84 → 1.0.85

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 CHANGED
@@ -607686,6 +607686,271 @@ var init_tool_policy = __esm({
607686
607686
  }
607687
607687
  });
607688
607688
 
607689
+ // packages/cli/src/tui/telegram-help-menu.ts
607690
+ function telegramSyntheticHelpSignatures() {
607691
+ return [
607692
+ { signature: "/help", description: "Show interactive command help" },
607693
+ { signature: "/start", description: "Show Telegram bridge status and authentication instructions" },
607694
+ { signature: "/auth <code>", description: "Authenticate this Telegram user as bot admin using the TUI code" },
607695
+ { signature: "/call", description: "Get the active voice call link when a call session is running" },
607696
+ { signature: "/reflect", description: "Run scoped Telegram chat reflection over retained chat history" },
607697
+ { signature: "/reflect status", description: "Show the latest scoped Telegram reflection artifact" },
607698
+ { signature: "/reflect now", description: "Run reflection and let the model decide whether to post a public follow-up" },
607699
+ { signature: "/reflect auto on|off", description: "Enable or disable model-gated idle follow-ups for this chat" },
607700
+ { signature: "/reflection", description: "Alias for /reflect" },
607701
+ { signature: "/daydream", description: "Alias for /reflect in Telegram chats" }
607702
+ ];
607703
+ }
607704
+ function telegramHelpCommandAllowed(cmd, scope) {
607705
+ if (cmd.name === "dream") return false;
607706
+ if (scope === "admin") return cmd.implementationStatus === "implemented";
607707
+ return TELEGRAM_PUBLIC_HELP_COMMANDS.has(cmd.name);
607708
+ }
607709
+ function parseArgsHint(argsHint) {
607710
+ if (!argsHint) return [];
607711
+ const args = [];
607712
+ const re = /<(\w+)(\?)?>/g;
607713
+ let match;
607714
+ while ((match = re.exec(argsHint)) !== null) {
607715
+ const name10 = match[1];
607716
+ const optional2 = match[2] === "?";
607717
+ args.push({
607718
+ name: name10,
607719
+ type: "string",
607720
+ required: !optional2,
607721
+ description: ""
607722
+ });
607723
+ }
607724
+ return args;
607725
+ }
607726
+ function buildScopedToolList(scope) {
607727
+ const commands = listCommandRegistry({ includePlanned: false }).filter((cmd) => telegramHelpCommandAllowed(cmd, scope));
607728
+ const syntheticSigs = telegramSyntheticHelpSignatures();
607729
+ const commandSigs = commands.flatMap((cmd) => cmd.signatures);
607730
+ const allSigs = [...syntheticSigs, ...commandSigs];
607731
+ const seen = /* @__PURE__ */ new Set();
607732
+ const unique = allSigs.filter((sig) => {
607733
+ if (seen.has(sig.signature)) return false;
607734
+ seen.add(sig.signature);
607735
+ return true;
607736
+ });
607737
+ const entries = [];
607738
+ for (const sig of unique) {
607739
+ const matchingCmd = commands.find(
607740
+ (cmd) => cmd.signatures.some((s2) => s2.signature === sig.signature)
607741
+ );
607742
+ const args = matchingCmd ? parseArgsHint(matchingCmd.argsHint) : [];
607743
+ const name10 = sig.signature.replace(/^\//, "").split(/\s+/)[0] ?? sig.signature;
607744
+ entries.push({
607745
+ name: name10,
607746
+ signature: sig.signature,
607747
+ description: sig.description,
607748
+ arguments: args
607749
+ });
607750
+ }
607751
+ return entries;
607752
+ }
607753
+ function encodeHelpCallback(action, value2) {
607754
+ const raw = `${CALLBACK_PREFIX}:${action}:${value2}`;
607755
+ return raw.slice(0, MAX_CALLBACK_DATA);
607756
+ }
607757
+ function decodeHelpCallback(data) {
607758
+ if (!data.startsWith(CALLBACK_PREFIX + ":")) return null;
607759
+ const parts = data.split(":");
607760
+ if (parts.length < 3) return null;
607761
+ const action = parts[1];
607762
+ const value2 = parts.slice(2).join(":");
607763
+ if (action !== "page" && action !== "detail" && action !== "back") return null;
607764
+ return { action, value: value2 };
607765
+ }
607766
+ function buildToolListKeyboard(tools, page2, scope) {
607767
+ const totalPages = Math.max(1, Math.ceil(tools.length / TOOLS_PER_PAGE));
607768
+ const start2 = page2 * TOOLS_PER_PAGE;
607769
+ const pageTools = tools.slice(start2, start2 + TOOLS_PER_PAGE);
607770
+ const rows = [];
607771
+ let currentRow = [];
607772
+ for (const tool of pageTools) {
607773
+ const label = tool.name.length > 18 ? tool.name.slice(0, 17) + "…" : tool.name;
607774
+ currentRow.push({
607775
+ text: label,
607776
+ callback_data: encodeHelpCallback("detail", tool.name)
607777
+ });
607778
+ if (currentRow.length >= GRID_COLS) {
607779
+ rows.push(currentRow);
607780
+ currentRow = [];
607781
+ }
607782
+ }
607783
+ if (currentRow.length > 0) {
607784
+ rows.push(currentRow);
607785
+ }
607786
+ const navRow = [];
607787
+ if (page2 > 0) {
607788
+ navRow.push({ text: "◀️ Back", callback_data: encodeHelpCallback("page", page2 - 1) });
607789
+ }
607790
+ navRow.push({
607791
+ text: `${page2 + 1}/${totalPages}`,
607792
+ callback_data: encodeHelpCallback("page", page2.toString())
607793
+ // re-send same page (no-op, just indicator)
607794
+ });
607795
+ if (page2 < totalPages - 1) {
607796
+ navRow.push({ text: "▶️ Next", callback_data: encodeHelpCallback("page", page2 + 1) });
607797
+ }
607798
+ rows.push(navRow);
607799
+ return rows;
607800
+ }
607801
+ function buildToolDetailKeyboard(tool, page2) {
607802
+ const rows = [];
607803
+ for (const arg of tool.arguments) {
607804
+ const req2 = arg.required ? "●" : "○";
607805
+ const label = `${req2} ${arg.name}`.slice(0, 30);
607806
+ rows.push([{
607807
+ text: label,
607808
+ callback_data: encodeHelpCallback("detail", tool.name)
607809
+ // stay on detail
607810
+ }]);
607811
+ }
607812
+ rows.push([{
607813
+ text: "🔙 Back to tools",
607814
+ callback_data: encodeHelpCallback("back", page2.toString())
607815
+ }]);
607816
+ return rows;
607817
+ }
607818
+ function escapeHTML(text) {
607819
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
607820
+ }
607821
+ function buildToolListText(tools, page2, scope) {
607822
+ const totalPages = Math.max(1, Math.ceil(tools.length / TOOLS_PER_PAGE));
607823
+ const start2 = page2 * TOOLS_PER_PAGE;
607824
+ const pageTools = tools.slice(start2, start2 + TOOLS_PER_PAGE);
607825
+ const lines = [
607826
+ `<b>🛠 Commands (${scope === "admin" ? "admin full scope" : "public secure scope"})</b>`,
607827
+ `<i>Page ${page2 + 1} of ${totalPages} — ${tools.length} commands</i>`,
607828
+ ""
607829
+ ];
607830
+ for (const tool of pageTools) {
607831
+ lines.push(`<code>${escapeHTML(tool.signature)}</code>`);
607832
+ lines.push(` ${escapeHTML(tool.description)}`);
607833
+ }
607834
+ lines.push("");
607835
+ lines.push("<i>Tap a command for details, or use ◀️▶️ to navigate.</i>");
607836
+ return lines.join("\n");
607837
+ }
607838
+ function buildToolDetailText(tool) {
607839
+ const lines = [
607840
+ `<b>📌 ${escapeHTML(tool.signature)}</b>`,
607841
+ "",
607842
+ escapeHTML(tool.description),
607843
+ ""
607844
+ ];
607845
+ if (tool.arguments.length > 0) {
607846
+ lines.push("<b>Arguments:</b>");
607847
+ lines.push("");
607848
+ for (const arg of tool.arguments) {
607849
+ const reqBadge = arg.required ? "<b>[required]</b>" : "<i>[optional]</i>";
607850
+ lines.push(`<code>${escapeHTML(arg.name)}</code> ${reqBadge} <i>${escapeHTML(arg.type)}</i>`);
607851
+ if (arg.description) {
607852
+ lines.push(` ${escapeHTML(arg.description)}`);
607853
+ }
607854
+ lines.push("");
607855
+ }
607856
+ } else {
607857
+ lines.push("<i>No arguments.</i>");
607858
+ }
607859
+ lines.push("🔙 <i>Tap Back to return to the tool list.</i>");
607860
+ return lines.join("\n");
607861
+ }
607862
+ function renderHelpMenu(scope) {
607863
+ const tools = buildScopedToolList(scope);
607864
+ const text = buildToolListText(tools, 0, scope);
607865
+ const inline_keyboard = buildToolListKeyboard(tools, 0, scope);
607866
+ return { text, replyMarkup: { inline_keyboard } };
607867
+ }
607868
+ function renderHelpMenuPage(scope, page2) {
607869
+ const tools = buildScopedToolList(scope);
607870
+ const totalPages = Math.max(1, Math.ceil(tools.length / TOOLS_PER_PAGE));
607871
+ page2 = Math.max(0, Math.min(page2, totalPages - 1));
607872
+ const text = buildToolListText(tools, page2, scope);
607873
+ const inline_keyboard = buildToolListKeyboard(tools, page2, scope);
607874
+ return { text, replyMarkup: { inline_keyboard } };
607875
+ }
607876
+ function renderHelpToolDetail(scope, toolName, returnPage) {
607877
+ const tools = buildScopedToolList(scope);
607878
+ const tool = tools.find((t2) => t2.name === toolName);
607879
+ if (!tool) return null;
607880
+ const text = buildToolDetailText(tool);
607881
+ const inline_keyboard = buildToolDetailKeyboard(tool, returnPage);
607882
+ return { text, replyMarkup: { inline_keyboard } };
607883
+ }
607884
+ function handleHelpCallback(callbackData, currentState) {
607885
+ const decoded = decodeHelpCallback(callbackData);
607886
+ if (!decoded) return null;
607887
+ const { action, value: value2 } = decoded;
607888
+ let newState;
607889
+ let render2;
607890
+ switch (action) {
607891
+ case "page": {
607892
+ const page2 = parseInt(value2, 10);
607893
+ if (isNaN(page2)) return null;
607894
+ render2 = renderHelpMenuPage(currentState.scope, page2);
607895
+ newState = { ...currentState, page: page2, view: "list", detailToolName: null };
607896
+ break;
607897
+ }
607898
+ case "detail": {
607899
+ const detail = renderHelpToolDetail(currentState.scope, value2, currentState.page);
607900
+ if (!detail) return null;
607901
+ render2 = detail;
607902
+ newState = { ...currentState, view: "detail", detailToolName: value2 };
607903
+ break;
607904
+ }
607905
+ case "back": {
607906
+ const page2 = parseInt(value2, 10);
607907
+ if (isNaN(page2)) return null;
607908
+ render2 = renderHelpMenuPage(currentState.scope, page2);
607909
+ newState = { ...currentState, page: page2, view: "list", detailToolName: null };
607910
+ break;
607911
+ }
607912
+ default:
607913
+ return null;
607914
+ }
607915
+ return { render: render2, newState };
607916
+ }
607917
+ var TOOLS_PER_PAGE, GRID_COLS, CALLBACK_PREFIX, MAX_CALLBACK_DATA, TELEGRAM_PUBLIC_HELP_COMMANDS, HelpMenuStateStore;
607918
+ var init_telegram_help_menu = __esm({
607919
+ "packages/cli/src/tui/telegram-help-menu.ts"() {
607920
+ "use strict";
607921
+ init_command_registry();
607922
+ TOOLS_PER_PAGE = 10;
607923
+ GRID_COLS = 5;
607924
+ CALLBACK_PREFIX = "help";
607925
+ MAX_CALLBACK_DATA = 64;
607926
+ TELEGRAM_PUBLIC_HELP_COMMANDS = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
607927
+ HelpMenuStateStore = class {
607928
+ states = /* @__PURE__ */ new Map();
607929
+ TTL_MS = 30 * 60 * 1e3;
607930
+ // 30 min
607931
+ key(chatId, messageId) {
607932
+ return `${chatId}:${messageId}`;
607933
+ }
607934
+ set(state) {
607935
+ this.states.set(this.key(state.chatId, state.messageId), state);
607936
+ }
607937
+ get(chatId, messageId) {
607938
+ return this.states.get(this.key(chatId, messageId));
607939
+ }
607940
+ delete(chatId, messageId) {
607941
+ this.states.delete(this.key(chatId, messageId));
607942
+ }
607943
+ /** Prune expired states */
607944
+ prune() {
607945
+ const now = Date.now();
607946
+ for (const [k, v] of this.states) {
607947
+ if (now - v.createdAt > this.TTL_MS) this.states.delete(k);
607948
+ }
607949
+ }
607950
+ };
607951
+ }
607952
+ });
607953
+
607689
607954
  // packages/cli/src/tui/telegram-creative-tools.ts
607690
607955
  import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes21 } from "node:crypto";
607691
607956
  import {
@@ -611355,7 +611620,7 @@ function splitTelegramReminderDue(raw) {
611355
611620
  if (suffixMatch) return { due: suffixMatch[2].trim(), message: suffixMatch[1].trim() };
611356
611621
  return { message: text };
611357
611622
  }
611358
- function telegramSyntheticHelpSignatures() {
611623
+ function telegramSyntheticHelpSignatures2() {
611359
611624
  return [
611360
611625
  { signature: "/help", description: "Show Telegram command help" },
611361
611626
  { signature: "/start", description: "Show Telegram bridge status and authentication instructions" },
@@ -611369,15 +611634,15 @@ function telegramSyntheticHelpSignatures() {
611369
611634
  { signature: "/daydream", description: "Alias for /reflect in Telegram chats" }
611370
611635
  ];
611371
611636
  }
611372
- function telegramHelpCommandAllowed(cmd, scope) {
611637
+ function telegramHelpCommandAllowed2(cmd, scope) {
611373
611638
  if (cmd.name === "dream") return false;
611374
611639
  if (scope === "admin") return cmd.implementationStatus === "implemented";
611375
- return TELEGRAM_PUBLIC_HELP_COMMANDS.has(cmd.name) || TELEGRAM_PUBLIC_BOT_COMMAND_NAMES.has(cmd.name);
611640
+ return TELEGRAM_PUBLIC_HELP_COMMANDS2.has(cmd.name) || TELEGRAM_PUBLIC_BOT_COMMAND_NAMES.has(cmd.name);
611376
611641
  }
611377
611642
  function buildTelegramHelpHTML(scope, maxPublicCommands = 24) {
611378
- const commands = listCommandRegistry({ includePlanned: false }).filter((cmd) => telegramHelpCommandAllowed(cmd, scope));
611643
+ const commands = listCommandRegistry({ includePlanned: false }).filter((cmd) => telegramHelpCommandAllowed2(cmd, scope));
611379
611644
  const signatures = [
611380
- ...telegramSyntheticHelpSignatures(),
611645
+ ...telegramSyntheticHelpSignatures2(),
611381
611646
  ...commands.flatMap((cmd) => cmd.signatures)
611382
611647
  ];
611383
611648
  const seen = /* @__PURE__ */ new Set();
@@ -612091,7 +612356,7 @@ function renderTelegramSubAgentError(username, error) {
612091
612356
  process.stdout.write(` ${c3.dim("│")} ${c3.red("✘")} @${username}: ${c3.dim(preview)}
612092
612357
  `);
612093
612358
  }
612094
- var TELEGRAM_TOOL_ACTION_GROUPS, TELEGRAM_TOOL_ACTION_GROUP, TELEGRAM_TOOL_MUTATING_GROUPS, DEFAULT_TELEGRAM_TOOL_GROUP_POLICY, TELEGRAM_TOOL_BUTTON_LABELS, TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, TELEGRAM_PUBLIC_VISION_STACK_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_EXTERNAL_ACQUISITION_CONTRACT, TELEGRAM_INTERACTION_DECISION_RESPONSE_FORMAT, TELEGRAM_STUCK_SELF_TALK_PREFIXES, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_ASSOCIATIVE_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_USER_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_ACTION_LIMIT, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_MEMORY_GENERIC_QUERY_TOKENS, TELEGRAM_SUB_AGENT_BOUNDED_OPTIONS, TELEGRAM_PUBLIC_HELP_COMMANDS, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_REFLECTION_SLASH_COMMANDS, TELEGRAM_PUBLIC_BOT_COMMAND_NAMES, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TELEGRAM_ALLOWED_UPDATES, TELEGRAM_PUBLIC_TOOL_QUOTAS, TelegramBridge;
612359
+ var TELEGRAM_TOOL_ACTION_GROUPS, TELEGRAM_TOOL_ACTION_GROUP, TELEGRAM_TOOL_MUTATING_GROUPS, DEFAULT_TELEGRAM_TOOL_GROUP_POLICY, TELEGRAM_TOOL_BUTTON_LABELS, TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, TELEGRAM_PUBLIC_VISION_STACK_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_EXTERNAL_ACQUISITION_CONTRACT, TELEGRAM_INTERACTION_DECISION_RESPONSE_FORMAT, TELEGRAM_STUCK_SELF_TALK_PREFIXES, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_ASSOCIATIVE_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_USER_FACT_LIMIT, TELEGRAM_ASSOCIATIVE_ACTION_LIMIT, TELEGRAM_ASSOCIATIVE_RELATION_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_MEMORY_GENERIC_QUERY_TOKENS, TELEGRAM_SUB_AGENT_BOUNDED_OPTIONS, TELEGRAM_PUBLIC_HELP_COMMANDS2, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_REFLECTION_SLASH_COMMANDS, TELEGRAM_PUBLIC_BOT_COMMAND_NAMES, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TELEGRAM_ALLOWED_UPDATES, TELEGRAM_PUBLIC_TOOL_QUOTAS, TelegramBridge;
612095
612360
  var init_telegram_bridge = __esm({
612096
612361
  "packages/cli/src/tui/telegram-bridge.ts"() {
612097
612362
  "use strict";
@@ -612102,6 +612367,7 @@ var init_telegram_bridge = __esm({
612102
612367
  init_tool_policy();
612103
612368
  init_media_routing();
612104
612369
  init_command_registry();
612370
+ init_telegram_help_menu();
612105
612371
  init_scoped_personality();
612106
612372
  init_telegram_creative_tools();
612107
612373
  init_omnius_directory();
@@ -612468,7 +612734,7 @@ External acquisition contract:
612468
612734
  bruteForceMaxCycles: 0,
612469
612735
  allowTurnExtension: false
612470
612736
  };
612471
- TELEGRAM_PUBLIC_HELP_COMMANDS = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
612737
+ TELEGRAM_PUBLIC_HELP_COMMANDS2 = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
612472
612738
  TELEGRAM_REMINDER_SLASH_COMMANDS = /* @__PURE__ */ new Set(["remind", "reminder", "reminders"]);
612473
612739
  TELEGRAM_REFLECTION_SLASH_COMMANDS = /* @__PURE__ */ new Set(["reflect", "reflection", "daydream", "dream"]);
612474
612740
  TELEGRAM_PUBLIC_BOT_COMMAND_NAMES = new Set(
@@ -612562,6 +612828,10 @@ External acquisition contract:
612562
612828
  telegramBotRightsCache = /* @__PURE__ */ new Map();
612563
612829
  /** Short-lived Telegram inline button state directory */
612564
612830
  telegramToolButtonDir;
612831
+ /** Interactive help menu state store (inline keyboard navigation) */
612832
+ helpMenuStates = new HelpMenuStateStore();
612833
+ /** Prune expired help menu states every 5 minutes */
612834
+ helpMenuPruneTimer = null;
612565
612835
  /** Command handler for admin DM slash commands (wired from interactive.ts) */
612566
612836
  commandHandler = null;
612567
612837
  /** Callback fired after a Telegram user completes the TUI-only admin auth challenge */
@@ -612983,21 +613253,30 @@ No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code
612983
613253
  }
612984
613254
  async replyWithTelegramHelp(msg, isAdmin) {
612985
613255
  const scope = isAdmin ? "admin" : "public";
612986
- const chunks = splitTelegramHTMLMessage(buildTelegramHelpHTML(scope));
613256
+ const menu = renderHelpMenu(scope);
612987
613257
  if (msg.guestQueryId) {
613258
+ const chunks = splitTelegramHTMLMessage(buildTelegramHelpHTML(isAdmin ? "admin" : "public"));
612988
613259
  await this.answerGuestQuery(msg.guestQueryId, chunks[0] ?? "", { parseMode: "HTML" });
612989
613260
  return;
612990
613261
  }
612991
- for (let i2 = 0; i2 < chunks.length; i2++) {
612992
- const chunk = chunks[i2];
612993
- if (i2 === 0) {
612994
- await this.replyToTelegramMessage(msg, chunk, {
612995
- html: true,
612996
- replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
612997
- });
612998
- } else {
612999
- await this.sendMessageHTML(msg.chatId, chunk);
613000
- }
613262
+ const sent = await this.apiCall("sendMessage", {
613263
+ chat_id: msg.chatId,
613264
+ text: menu.text,
613265
+ parse_mode: "HTML",
613266
+ reply_markup: JSON.stringify(menu.replyMarkup),
613267
+ ...msg.chatType !== "private" ? { reply_to_message_id: msg.messageId } : {}
613268
+ });
613269
+ if (sent.ok && sent.result?.message_id) {
613270
+ this.helpMenuStates.set({
613271
+ chatId: msg.chatId,
613272
+ messageId: sent.result.message_id,
613273
+ scope,
613274
+ page: 0,
613275
+ view: "list",
613276
+ detailToolName: null,
613277
+ fromUserId: msg.fromUserId ?? 0,
613278
+ createdAt: Date.now()
613279
+ });
613001
613280
  }
613002
613281
  }
613003
613282
  recordChatHistory(sessionKey, entry) {
@@ -619310,6 +619589,57 @@ Scoped workspace: ${scopedRoot}`,
619310
619589
  return Boolean(result.ok);
619311
619590
  }
619312
619591
  async handleTelegramCallbackQuery(callback) {
619592
+ const helpDecoded = decodeHelpCallback(callback.data);
619593
+ if (helpDecoded) {
619594
+ let answerText2 = "";
619595
+ let alert2 = false;
619596
+ try {
619597
+ const chatId = callback.chatId;
619598
+ const messageId = callback.messageId;
619599
+ if (!chatId || !messageId) {
619600
+ answerText2 = "Cannot identify menu message.";
619601
+ alert2 = true;
619602
+ return;
619603
+ }
619604
+ const menuState = this.helpMenuStates.get(chatId, messageId);
619605
+ if (!menuState) {
619606
+ answerText2 = "This help menu expired. Send /help for a fresh one.";
619607
+ alert2 = true;
619608
+ return;
619609
+ }
619610
+ const isAdmin = this.isAdminActor(callback.fromUserId, callback.username);
619611
+ if (callback.fromUserId !== menuState.fromUserId && !isAdmin) {
619612
+ answerText2 = "Only the user who opened this menu can navigate it.";
619613
+ alert2 = true;
619614
+ return;
619615
+ }
619616
+ const result = handleHelpCallback(callback.data, menuState);
619617
+ if (!result) {
619618
+ answerText2 = "Unknown menu action.";
619619
+ alert2 = true;
619620
+ return;
619621
+ }
619622
+ this.helpMenuStates.set(result.newState);
619623
+ await this.apiCall("editMessageText", {
619624
+ chat_id: chatId,
619625
+ message_id: messageId,
619626
+ text: result.render.text,
619627
+ parse_mode: "HTML",
619628
+ reply_markup: JSON.stringify(result.render.replyMarkup)
619629
+ });
619630
+ answerText2 = "";
619631
+ } catch (err) {
619632
+ answerText2 = err instanceof Error ? err.message : String(err);
619633
+ alert2 = true;
619634
+ } finally {
619635
+ if (answerText2) {
619636
+ await this.answerCallbackQuery(callback.id, answerText2.slice(0, 180), alert2).catch(() => false);
619637
+ } else {
619638
+ await this.answerCallbackQuery(callback.id).catch(() => false);
619639
+ }
619640
+ }
619641
+ return;
619642
+ }
619313
619643
  let answerText = "Updated.";
619314
619644
  let alert = false;
619315
619645
  try {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.84",
3
+ "version": "1.0.85",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.84",
9
+ "version": "1.0.85",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.84",
3
+ "version": "1.0.85",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",