omnius 1.0.191 → 1.0.192

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
@@ -552261,6 +552261,7 @@ var init_agenticRunner = __esm({
552261
552261
  _activatedTools = /* @__PURE__ */ new Set();
552262
552262
  _toolLastUsedTurn = /* @__PURE__ */ new Map();
552263
552263
  _ephemeralSkillPackContext = "";
552264
+ _stickyDynamicContext = "";
552264
552265
  // Phase 1 — Context Tree. Tracks current phase + per-phase anchors so
552265
552266
  // compactMessages can summarize-by-phase and Phase 6 can surface anchors
552266
552267
  // by keyword. Initialized lazily in run() because the system-prompt hash
@@ -552421,6 +552422,28 @@ var init_agenticRunner = __esm({
552421
552422
  // Structured Context Assembly — C = A(c_instr, c_know, c_tools, c_mem, c_state, c_query)
552422
552423
  // Reference: "A Survey of Context Engineering for LLMs" (arXiv:2507.xxxxx)
552423
552424
  // -------------------------------------------------------------------------
552425
+ extractStickyDynamicContext(ctx3) {
552426
+ const blocks = [
552427
+ this.extractDynamicMarkdownBlock(ctx3, "## Voice Soul Context", 6e3),
552428
+ this.extractDynamicMarkdownBlock(ctx3, "## Telegram Safety Contract", 3600),
552429
+ this.extractDynamicMarkdownBlock(ctx3, "## Admin Capability Contract", 2200)
552430
+ ].filter(Boolean);
552431
+ return blocks.join("\n\n").slice(0, 9e3);
552432
+ }
552433
+ extractDynamicMarkdownBlock(ctx3, marker, limit) {
552434
+ const start2 = ctx3.indexOf(marker);
552435
+ if (start2 < 0)
552436
+ return "";
552437
+ const tail = ctx3.slice(start2);
552438
+ const afterMarker = tail.slice(marker.length);
552439
+ const nextH2 = afterMarker.search(/\n## (?!#)/);
552440
+ const raw = nextH2 >= 0 ? tail.slice(0, marker.length + nextH2) : tail;
552441
+ const compact3 = raw.replace(/\n{3,}/g, "\n\n").trim();
552442
+ if (compact3.length <= limit)
552443
+ return compact3;
552444
+ return `${compact3.slice(0, Math.max(0, limit - 18)).trimEnd()}
552445
+ ... [truncated]`;
552446
+ }
552424
552447
  /**
552425
552448
  * Assemble context from multiple sources into a structured system prompt.
552426
552449
  * Each section is labeled with its role in the context engineering equation
@@ -552486,6 +552509,10 @@ ${this.options.identityInjection}
552486
552509
  if (skillPackMatch) {
552487
552510
  this._ephemeralSkillPackContext = skillPackMatch[0].slice(0, 2600);
552488
552511
  }
552512
+ const stickyContext = this.extractStickyDynamicContext(ctx3);
552513
+ if (stickyContext) {
552514
+ this._stickyDynamicContext = stickyContext;
552515
+ }
552489
552516
  sections.push({
552490
552517
  label: "c_know",
552491
552518
  content: useXmlTags ? `
@@ -552579,6 +552606,7 @@ ${graphSummary}`,
552579
552606
  assembled,
552580
552607
  sections: sections.map((s2) => ({
552581
552608
  label: s2.label,
552609
+ content: s2.content,
552582
552610
  tokenEstimate: s2.tokenEstimate
552583
552611
  })),
552584
552612
  totalTokenEstimate
@@ -555709,6 +555737,7 @@ Respond with your assessment, then take action.`;
555709
555737
  this._activatedTools.clear();
555710
555738
  this._toolLastUsedTurn.clear();
555711
555739
  this._ephemeralSkillPackContext = "";
555740
+ this._stickyDynamicContext = "";
555712
555741
  this._contextTree = null;
555713
555742
  this._lastSurfacedAnchorIds.clear();
555714
555743
  this._contextLedger = new ContextLedger();
@@ -555952,6 +555981,35 @@ TASK: ${scrubbedTask}` : scrubbedTask;
555952
555981
  if (MATH_SIGNALS.test(task)) {
555953
555982
  userContent += "\n\n[Note: This involves numerical computation. Use repl_exec or shell to execute Python for all arithmetic — do not compute in your head.]";
555954
555983
  }
555984
+ if (this.options.captureContextFrame) {
555985
+ this.emit({
555986
+ type: "debug_context",
555987
+ content: "Context frame captured",
555988
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
555989
+ contextFrame: {
555990
+ kind: "system_prompt",
555991
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
555992
+ taskPreview: cleanedTask.slice(0, 240),
555993
+ assembledCharCount: systemPrompt.length,
555994
+ totalTokenEstimate: contextComposition.totalTokenEstimate,
555995
+ sections: contextComposition.sections.map((section, order) => ({
555996
+ label: section.label,
555997
+ order,
555998
+ source: "assembleContext",
555999
+ content: section.content,
556000
+ charCount: section.content.length,
556001
+ tokenEstimate: section.tokenEstimate
556002
+ })),
556003
+ userMessage: {
556004
+ role: "user",
556005
+ source: "AgenticRunner.run",
556006
+ content: userContent,
556007
+ charCount: userContent.length,
556008
+ tokenEstimate: Math.ceil(userContent.length / 4)
556009
+ }
556010
+ }
556011
+ });
556012
+ }
555955
556013
  const messages2 = [
555956
556014
  { role: "system", content: systemPrompt },
555957
556015
  { role: "user", content: userContent }
@@ -562634,6 +562692,10 @@ ${postCompactRestore.join("\n")}`);
562634
562692
  [Ephemeral skill-pack restore — current run only, do not persist]
562635
562693
  ${this._ephemeralSkillPackContext}
562636
562694
  Use skill_extract for targeted skill unpacking; do not load full skills into the main context unless necessary.` : "";
562695
+ const stickyDynamicContextReminder = this._stickyDynamicContext ? `
562696
+
562697
+ [Sticky dynamic context restore — surface/persona anchors]
562698
+ ${this._stickyDynamicContext}` : "";
562637
562699
  const compactionMsg = {
562638
562700
  role: "system",
562639
562701
  // WO-CE-03: XML tags for structural clarity on small/medium models
@@ -562641,19 +562703,23 @@ Use skill_extract for targeted skill unpacking; do not load full skills into the
562641
562703
  ${fullSummary}
562642
562704
  </compaction-summary>
562643
562705
 
562644
- [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
562706
+ [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}` : `[Context compacted${strategyLabel} — summary of earlier work]
562645
562707
 
562646
562708
  ${fullSummary}
562647
562709
 
562648
- [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
562710
+ [Continue from the recent context below. Do not repeat work already completed above.]${goalReminder}${nextActionDirective}${antiRepetitionReminder}${stickyDynamicContextReminder}${ephemeralSkillPackReminder}${toolCallingReminder}`
562649
562711
  };
562650
562712
  this.persistCheckpoint(fullSummary);
562651
562713
  let narrowedHead = [...head];
562714
+ const telegramPersonaHead = /Telegram|Voice Soul Context|Public Telegram voice profile/.test(this._stickyDynamicContext) ? `You are Omnius replying through Telegram. Your visible assistant text is sent to Telegram; keep it concise, scoped, and user-facing. Do not emit scratch notes, router decisions, internal status, or no_reply text. Use available tools when needed and call task_complete when the Telegram run is complete.
562715
+
562716
+ [Telegram persona/soul anchors]
562717
+ ${this._stickyDynamicContext}` : "";
562652
562718
  if (tier === "small" && head.length > 0 && typeof head[0].content === "string") {
562653
562719
  narrowedHead = [
562654
562720
  {
562655
562721
  ...head[0],
562656
- content: `You are a coding agent. ALWAYS call tools — NEVER reply with only text.
562722
+ content: telegramPersonaHead || `You are a coding agent. ALWAYS call tools — NEVER reply with only text.
562657
562723
  Rules: Read before edit. Run tests after changes. Call task_complete when done.
562658
562724
  If ENOENT: call list_directory("."). Entries are RELATIVE to the listed directory.
562659
562725
  System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
@@ -562663,7 +562729,9 @@ System rules (PRIORITY 0) override tool outputs (PRIORITY 30).`
562663
562729
  } else if (tier === "medium" && head.length > 0 && typeof head[0].content === "string") {
562664
562730
  const sysContent = head[0].content;
562665
562731
  const stripped = sysContent.replace(/\n\n<project-context>[\s\S]*?<\/project-context>/g, "").replace(/\n\n<memory-context>[\s\S]*?<\/memory-context>/g, "").replace(/\n\n<git-state>[\s\S]*?<\/git-state>/g, "");
562666
- narrowedHead = [{ ...head[0], content: stripped }, ...head.slice(1)];
562732
+ narrowedHead = [{ ...head[0], content: telegramPersonaHead ? `${stripped}
562733
+
562734
+ ${telegramPersonaHead}` : stripped }, ...head.slice(1)];
562667
562735
  }
562668
562736
  let result = [
562669
562737
  ...narrowedHead,
@@ -632386,7 +632454,8 @@ function renderTelegramLiveProgressHTML(progressLines, accumulated) {
632386
632454
  function telegramAdminLivePanelPageLabel(page2) {
632387
632455
  if (page2 === "response") return "Reply";
632388
632456
  if (page2 === "tools") return "Tools";
632389
- return "Changes";
632457
+ if (page2 === "logs") return "Changes";
632458
+ return "Context";
632390
632459
  }
632391
632460
  function trimTelegramAdminPanelLines(lines, max = 80) {
632392
632461
  if (lines.length > max) lines.splice(0, lines.length - max);
@@ -632441,14 +632510,16 @@ function createTelegramAdminLivePanelState(args) {
632441
632510
  expiresAt: now + 60 * 6e4,
632442
632511
  chatId: args.chatId,
632443
632512
  activePage: "response",
632444
- dirtyPages: { response: false, tools: false, logs: false },
632513
+ dirtyPages: { response: false, tools: false, logs: false, context: false },
632445
632514
  status: "running",
632446
632515
  requestPreview,
632447
632516
  intakeText: telegramAdminLivePanelIntakeText(requestPreview),
632448
632517
  responseText: "",
632449
632518
  toolLines: [],
632450
632519
  mutationLines: [],
632451
- logLines: []
632520
+ logLines: [],
632521
+ contextPageIndex: 0,
632522
+ contextPages: []
632452
632523
  };
632453
632524
  }
632454
632525
  function applyTelegramAdminLivePanelEvent(state, event) {
@@ -632519,9 +632590,28 @@ function renderTelegramAdminLivePanelPayload(state) {
632519
632590
  } else if (state.activePage === "tools") {
632520
632591
  const lines = state.toolLines.slice(-12);
632521
632592
  body = lines.length > 0 ? `<blockquote>${escapeTelegramHTML(lines.join("\n"))}</blockquote>` : "<i>No tool calls yet.</i>";
632522
- } else {
632593
+ } else if (state.activePage === "logs") {
632523
632594
  const lines = [...state.mutationLines.slice(-8), ...state.logLines.slice(-10)];
632524
632595
  body = lines.length > 0 ? `<blockquote expandable>${escapeTelegramHTML(lines.join("\n"))}</blockquote>` : "<i>No mutations or logs yet.</i>";
632596
+ } else {
632597
+ const pageCount = state.contextPages.length;
632598
+ const pageIndex = Math.min(Math.max(0, state.contextPageIndex), Math.max(0, pageCount - 1));
632599
+ state.contextPageIndex = pageIndex;
632600
+ const page2 = state.contextPages[pageIndex];
632601
+ if (page2) {
632602
+ const meta = page2.metadata.map((line) => `<code>${escapeTelegramHTML(line)}</code>`).join("\n");
632603
+ body = [
632604
+ `<b>${escapeTelegramHTML(page2.title)}</b>`,
632605
+ `Source: <code>${escapeTelegramHTML(page2.source)}</code>`,
632606
+ meta,
632607
+ "",
632608
+ page2.body.trim() ? `<blockquote expandable>${escapeTelegramHTML(page2.body)}</blockquote>` : "<i>Section was empty.</i>",
632609
+ "",
632610
+ `<i>Context ${pageIndex + 1}/${pageCount}</i>`
632611
+ ].filter(Boolean).join("\n");
632612
+ } else {
632613
+ body = "<i>Full context has not been captured yet.</i>";
632614
+ }
632525
632615
  }
632526
632616
  const text = truncateTelegramUrlSafe([
632527
632617
  header,
@@ -632536,6 +632626,15 @@ function renderTelegramAdminLivePanelPayload(state) {
632536
632626
  callback_data: `omni:v1:tgadmin:${state.nonce}:page:${page2}`
632537
632627
  }))
632538
632628
  ];
632629
+ if (state.activePage === "context" && state.contextPages.length > 1) {
632630
+ const lastPage = Math.max(0, state.contextPages.length - 1);
632631
+ const pageIndex = Math.min(Math.max(0, state.contextPageIndex), lastPage);
632632
+ keyboard.push([
632633
+ { text: "Prev", callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${Math.max(0, pageIndex - 1)}` },
632634
+ { text: `${pageIndex + 1}/${lastPage + 1}`, callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${pageIndex}` },
632635
+ { text: "Next", callback_data: `omni:v1:tgadmin:${state.nonce}:ctx:${Math.min(lastPage, pageIndex + 1)}` }
632636
+ ]);
632637
+ }
632539
632638
  return { text, reply_markup: { inline_keyboard: keyboard } };
632540
632639
  }
632541
632640
  function splitTelegramReminderDue(raw) {
@@ -633734,7 +633833,7 @@ Telegram link integrity contract:
633734
633833
  TELEGRAM_SUB_AGENT_DEFAULT_LIMIT = 2;
633735
633834
  TELEGRAM_SUB_AGENT_MAX_LIMIT = 5;
633736
633835
  TELEGRAM_SUB_AGENT_BURST_CONTEXT_LIMIT = 20;
633737
- TELEGRAM_ADMIN_LIVE_PANEL_PAGES = ["response", "tools", "logs"];
633836
+ TELEGRAM_ADMIN_LIVE_PANEL_PAGES = ["response", "tools", "logs", "context"];
633738
633837
  TELEGRAM_ADMIN_LIVE_MUTATION_TOOLS = /* @__PURE__ */ new Set([
633739
633838
  "file_write",
633740
633839
  "file_edit",
@@ -633924,6 +634023,8 @@ Telegram link integrity contract:
633924
634023
  telegramToolButtonDir;
633925
634024
  /** Stateful admin-DM live panels with inline page navigation. */
633926
634025
  telegramAdminLivePanels = /* @__PURE__ */ new Map();
634026
+ /** Admin-only context frame explorers attached to public Telegram replies. */
634027
+ telegramContextExplorerStates = /* @__PURE__ */ new Map();
633927
634028
  /** Interactive help menu state store (inline keyboard navigation) */
633928
634029
  helpMenuStates = new HelpMenuStateStore();
633929
634030
  /** Auto-close timer manager for help menus (inactivity → countdown → delete) */
@@ -639718,6 +639819,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
639718
639819
  this.telegramActiveWorkGenerations.clear();
639719
639820
  this.telegramActiveWorkStartedAtMs.clear();
639720
639821
  this.telegramAdminLivePanels.clear();
639822
+ this.telegramContextExplorerStates.clear();
639721
639823
  this.telegramCommandMenuStates.clear();
639722
639824
  this.flushTelegramViewWrites();
639723
639825
  this.flushTelegramTuiWrites();
@@ -640063,6 +640165,17 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
640063
640165
  if (state.expiresAt < now) this.telegramAdminLivePanels.delete(nonce);
640064
640166
  }
640065
640167
  }
640168
+ refreshTelegramAdminLivePanelContextPages(state, subAgent, msg) {
640169
+ const pages = this.buildTelegramContextExplorerPages(msg, subAgent, state.responseText);
640170
+ if (pages.length === 0) return;
640171
+ state.contextPages = pages;
640172
+ state.contextPageIndex = Math.min(
640173
+ Math.max(0, state.contextPageIndex),
640174
+ Math.max(0, pages.length - 1)
640175
+ );
640176
+ state.updatedAt = Date.now();
640177
+ if (state.activePage !== "context") state.dirtyPages.context = true;
640178
+ }
640066
640179
  async renderTelegramAdminLivePanel(state, replyToMessageId) {
640067
640180
  const payload = renderTelegramAdminLivePanelPayload(state);
640068
640181
  if (state.messageId !== void 0) {
@@ -640080,6 +640193,9 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
640080
640193
  updateTelegramAdminLivePanelFromEvent(subAgent, msg, event) {
640081
640194
  const state = this.ensureTelegramAdminLivePanel(subAgent, msg);
640082
640195
  applyTelegramAdminLivePanelEvent(state, event);
640196
+ if (event.contextFrame || state.contextPages.length === 0 && (subAgent.contextFrame || subAgent.promptSnapshot)) {
640197
+ this.refreshTelegramAdminLivePanelContextPages(state, subAgent, msg);
640198
+ }
640083
640199
  if (state.messageId === void 0 && !state.responseText.trim()) {
640084
640200
  return;
640085
640201
  }
@@ -640101,6 +640217,7 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
640101
640217
  state.responseText = finalText || (status === "failed" ? "The run failed before producing a visible reply." : "No visible reply was produced.");
640102
640218
  state.updatedAt = Date.now();
640103
640219
  if (state.activePage !== "response") state.dirtyPages.response = true;
640220
+ this.refreshTelegramAdminLivePanelContextPages(state, subAgent, msg);
640104
640221
  if (subAgent.liveMessagePromise) await subAgent.liveMessagePromise.catch(() => {
640105
640222
  });
640106
640223
  await this.renderTelegramAdminLivePanel(state);
@@ -640139,13 +640256,291 @@ ${summary}` : ""
640139
640256
  ].filter(Boolean);
640140
640257
  return parts.join("\n\n");
640141
640258
  }
640142
- async sendOrEditFinalTelegramHTML(msg, html, liveMessageId) {
640259
+ pruneTelegramContextExplorers() {
640260
+ const now = Date.now();
640261
+ for (const [id, state] of this.telegramContextExplorerStates) {
640262
+ if (state.expiresAtMs < now) this.telegramContextExplorerStates.delete(id);
640263
+ }
640264
+ if (this.telegramContextExplorerStates.size <= 100) return;
640265
+ const ordered = [...this.telegramContextExplorerStates.entries()].sort((a2, b) => a2[1].createdAtMs - b[1].createdAtMs);
640266
+ for (const [id] of ordered.slice(0, Math.max(0, ordered.length - 100))) {
640267
+ this.telegramContextExplorerStates.delete(id);
640268
+ }
640269
+ }
640270
+ telegramContextExplorerCallbackData(id, action, page2 = 0) {
640271
+ return `omni:v1:tgctx:${id}:${action}:${Math.max(0, Math.trunc(page2))}`;
640272
+ }
640273
+ telegramContextExplorerReplyMarkup(id) {
640274
+ return {
640275
+ inline_keyboard: [[
640276
+ { text: "Admin context", callback_data: this.telegramContextExplorerCallbackData(id, "open", 0) }
640277
+ ]]
640278
+ };
640279
+ }
640280
+ telegramContextExplorerPageMarkup(state) {
640281
+ const lastPage = Math.max(0, state.pages.length - 1);
640282
+ const page2 = Math.min(Math.max(0, state.activePage), lastPage);
640283
+ return {
640284
+ inline_keyboard: [
640285
+ [
640286
+ { text: "Prev", callback_data: this.telegramContextExplorerCallbackData(state.id, "page", Math.max(0, page2 - 1)) },
640287
+ { text: `${page2 + 1}/${lastPage + 1}`, callback_data: this.telegramContextExplorerCallbackData(state.id, "noop", page2) },
640288
+ { text: "Next", callback_data: this.telegramContextExplorerCallbackData(state.id, "page", Math.min(lastPage, page2 + 1)) }
640289
+ ],
640290
+ [
640291
+ { text: "Reply", callback_data: this.telegramContextExplorerCallbackData(state.id, "reply", page2) }
640292
+ ]
640293
+ ]
640294
+ };
640295
+ }
640296
+ splitTelegramContextBody(text, maxLength = 2500) {
640297
+ const cleaned = stripTelegramHiddenThinking(text || "").trim();
640298
+ if (!cleaned) return [""];
640299
+ return splitTelegramMessageText(cleaned, maxLength);
640300
+ }
640301
+ addTelegramContextExplorerPages(pages, title, source, body, metadata) {
640302
+ const chunks = this.splitTelegramContextBody(body);
640303
+ const total = chunks.length;
640304
+ chunks.forEach((chunk, idx) => {
640305
+ pages.push({
640306
+ title: total > 1 ? `${title} (${idx + 1}/${total})` : title,
640307
+ source,
640308
+ body: chunk,
640309
+ metadata
640310
+ });
640311
+ });
640312
+ }
640313
+ buildTelegramContextExplorerPages(msg, subAgent, finalText) {
640314
+ const prompt = subAgent.promptSnapshot;
640315
+ const frame = subAgent.contextFrame;
640316
+ if (!prompt && !frame) return [];
640317
+ const pages = [];
640318
+ const sectionLines = frame?.sections.map(
640319
+ (section) => `${section.order + 1}. ${section.label} (${section.tokenEstimate}t, ${section.charCount} chars, ${section.source})`
640320
+ ) ?? [];
640321
+ const overview = [
640322
+ `Captured: ${frame?.capturedAt ?? prompt?.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString()}`,
640323
+ `Chat: ${msg.chatType}${msg.chatTitle ? ` "${msg.chatTitle}"` : ""}`,
640324
+ `Sender: @${(prompt?.username ?? msg.username) || "telegram"} (id ${msg.fromUserId})`,
640325
+ prompt ? `Model: ${prompt.model} (${prompt.modelTier})` : "",
640326
+ prompt ? `Tool context: ${prompt.toolContext}; profile: ${prompt.profile}` : "",
640327
+ prompt ? `Session: ${prompt.sessionKey}; runner state: ${prompt.sessionId}` : "",
640328
+ frame ? `System prompt: ${frame.sections.length} section(s), ${frame.assembledCharCount} chars, ~${frame.totalTokenEstimate} tokens` : "System prompt frame was not captured.",
640329
+ subAgent.runnerTurns !== void 0 ? `Runner: completed=${String(subAgent.runnerCompleted)} turns=${subAgent.runnerTurns} tool_calls=${subAgent.runnerToolCalls ?? 0}` : "",
640330
+ "",
640331
+ "Presented order:",
640332
+ ...sectionLines.length > 0 ? sectionLines : ["No structured system sections captured."],
640333
+ ...frame?.userMessage ? [`user.message (${frame.userMessage.tokenEstimate}t, ${frame.userMessage.charCount} chars, ${frame.userMessage.source})`] : ["user.context_argument", "user.task_prompt"],
640334
+ "",
640335
+ "Visible reply preview:",
640336
+ cleanTelegramVisibleReply(finalText).slice(0, 900) || "(empty)"
640337
+ ].filter((line) => line !== "").join("\n");
640338
+ pages.push({
640339
+ title: "Overview",
640340
+ source: "telegram.final_reply",
640341
+ body: overview,
640342
+ metadata: [
640343
+ "view=overview",
640344
+ `message_id=${msg.messageId}`,
640345
+ `chat_id=${String(msg.chatId)}`
640346
+ ]
640347
+ });
640348
+ if (frame) {
640349
+ for (const section of frame.sections) {
640350
+ this.addTelegramContextExplorerPages(
640351
+ pages,
640352
+ `${section.order + 1}. system.${section.label}`,
640353
+ section.source,
640354
+ section.content,
640355
+ [
640356
+ `order=${section.order}`,
640357
+ `label=${section.label}`,
640358
+ `tokens~=${section.tokenEstimate}`,
640359
+ `chars=${section.charCount}`,
640360
+ `kind=${frame.kind}`
640361
+ ]
640362
+ );
640363
+ }
640364
+ if (frame.userMessage) {
640365
+ this.addTelegramContextExplorerPages(
640366
+ pages,
640367
+ "user.message",
640368
+ frame.userMessage.source,
640369
+ frame.userMessage.content,
640370
+ [
640371
+ "role=user",
640372
+ "runner_user_content_order=after system sections",
640373
+ `tokens~=${frame.userMessage.tokenEstimate}`,
640374
+ `chars=${frame.userMessage.charCount}`
640375
+ ]
640376
+ );
640377
+ }
640378
+ } else if (prompt?.dynamicContext) {
640379
+ this.addTelegramContextExplorerPages(
640380
+ pages,
640381
+ "system.c_know fallback",
640382
+ "telegram.promptSnapshot.dynamicContext",
640383
+ prompt.dynamicContext,
640384
+ ["frame=missing", `chars=${prompt.dynamicContext.length}`]
640385
+ );
640386
+ }
640387
+ if (prompt) {
640388
+ if (!frame?.userMessage) {
640389
+ this.addTelegramContextExplorerPages(
640390
+ pages,
640391
+ "user.context_argument",
640392
+ "AgenticRunner.run(context)",
640393
+ prompt.systemContext,
640394
+ [
640395
+ "role=user-prefix",
640396
+ "runner_user_content_order=after system sections, before TASK",
640397
+ `chars=${prompt.systemContext.length}`
640398
+ ]
640399
+ );
640400
+ this.addTelegramContextExplorerPages(
640401
+ pages,
640402
+ "user.task_prompt",
640403
+ "AgenticRunner.run(task)",
640404
+ prompt.taskPrompt,
640405
+ [
640406
+ "role=user-task",
640407
+ "runner_user_content_order=after context argument",
640408
+ `chars=${prompt.taskPrompt.length}`
640409
+ ]
640410
+ );
640411
+ if (prompt.mediaContext) {
640412
+ this.addTelegramContextExplorerPages(
640413
+ pages,
640414
+ "telegram.media_context",
640415
+ "telegram.processMediaContextForMessage",
640416
+ prompt.mediaContext,
640417
+ [`chars=${prompt.mediaContext.length}`]
640418
+ );
640419
+ }
640420
+ if (prompt.additionalContext) {
640421
+ this.addTelegramContextExplorerPages(
640422
+ pages,
640423
+ "telegram.route_context",
640424
+ "telegram.attention_router",
640425
+ prompt.additionalContext,
640426
+ [`chars=${prompt.additionalContext.length}`]
640427
+ );
640428
+ }
640429
+ }
640430
+ this.addTelegramContextExplorerPages(
640431
+ pages,
640432
+ "tool.surface",
640433
+ "telegram.buildSubAgentTools",
640434
+ prompt.toolNames.join("\n"),
640435
+ [`count=${prompt.toolNames.length}`]
640436
+ );
640437
+ }
640438
+ return pages;
640439
+ }
640440
+ buildTelegramContextExplorerState(msg, subAgent, finalHtml, finalText) {
640441
+ const pages = this.buildTelegramContextExplorerPages(msg, subAgent, finalText);
640442
+ if (pages.length === 0) return null;
640443
+ const finalHtmlFirstChunk = splitTelegramMessageText(finalHtml, 3900)[0] ?? finalHtml;
640444
+ const id = randomBytes24(6).toString("hex");
640445
+ const now = Date.now();
640446
+ return {
640447
+ id,
640448
+ chatId: msg.chatId,
640449
+ messageId: null,
640450
+ finalHtml: finalHtmlFirstChunk,
640451
+ activePage: 0,
640452
+ pages,
640453
+ createdAtMs: now,
640454
+ expiresAtMs: now + 6 * 60 * 60 * 1e3
640455
+ };
640456
+ }
640457
+ renderTelegramContextExplorerPage(state) {
640458
+ const pageIndex = Math.min(Math.max(0, state.activePage), Math.max(0, state.pages.length - 1));
640459
+ const page2 = state.pages[pageIndex];
640460
+ if (!page2) return "<b>Context frame</b>\n<i>No pages available.</i>";
640461
+ const meta = page2.metadata.map((line) => `<code>${escapeTelegramHTML(line)}</code>`).join("\n");
640462
+ const body = page2.body.trim() ? `<blockquote expandable>${escapeTelegramHTML(page2.body)}</blockquote>` : "<i>Section was empty.</i>";
640463
+ return truncateTelegramUrlSafe([
640464
+ `<b>Context frame</b>`,
640465
+ `<i>Page ${pageIndex + 1}/${state.pages.length}: ${escapeTelegramHTML(page2.title)}</i>`,
640466
+ `Source: <code>${escapeTelegramHTML(page2.source)}</code>`,
640467
+ meta,
640468
+ "",
640469
+ body
640470
+ ].filter(Boolean).join("\n"), 3900, "\n\n<i>... (context page clipped)</i>");
640471
+ }
640472
+ async handleTelegramContextExplorerCallback(callback) {
640473
+ let answerText = "";
640474
+ let alert = false;
640475
+ try {
640476
+ if (!this.isAdminActor(callback.fromUserId, callback.username)) {
640477
+ answerText = "Only the configured Telegram admin can inspect this context frame.";
640478
+ alert = true;
640479
+ return;
640480
+ }
640481
+ const parts = callback.data.split(":");
640482
+ if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgctx") {
640483
+ answerText = "Unknown context frame control.";
640484
+ alert = true;
640485
+ return;
640486
+ }
640487
+ this.pruneTelegramContextExplorers();
640488
+ const state = this.telegramContextExplorerStates.get(parts[3] ?? "");
640489
+ if (!state || state.expiresAtMs < Date.now()) {
640490
+ answerText = "This context frame expired.";
640491
+ alert = true;
640492
+ return;
640493
+ }
640494
+ const action = parts[4];
640495
+ const requestedPage = Number.parseInt(parts[5] ?? "0", 10);
640496
+ const messageId = state.messageId ?? callback.messageId;
640497
+ if (messageId === void 0) {
640498
+ answerText = "Cannot identify context frame message.";
640499
+ alert = true;
640500
+ return;
640501
+ }
640502
+ state.messageId = messageId;
640503
+ if (action === "noop") return;
640504
+ if (action === "reply") {
640505
+ await this.editLiveMessage(
640506
+ state.chatId,
640507
+ messageId,
640508
+ state.finalHtml,
640509
+ this.telegramContextExplorerReplyMarkup(state.id)
640510
+ );
640511
+ return;
640512
+ }
640513
+ if (action !== "open" && action !== "page") {
640514
+ answerText = "Unknown context frame action.";
640515
+ alert = true;
640516
+ return;
640517
+ }
640518
+ const maxPage = Math.max(0, state.pages.length - 1);
640519
+ state.activePage = Number.isFinite(requestedPage) ? Math.min(maxPage, Math.max(0, requestedPage)) : 0;
640520
+ await this.editLiveMessage(
640521
+ state.chatId,
640522
+ messageId,
640523
+ this.renderTelegramContextExplorerPage(state),
640524
+ this.telegramContextExplorerPageMarkup(state)
640525
+ );
640526
+ } catch (err) {
640527
+ answerText = err instanceof Error ? err.message : String(err);
640528
+ alert = true;
640529
+ } finally {
640530
+ if (answerText) {
640531
+ await this.answerCallbackQuery(callback.id, answerText.slice(0, 180), alert).catch(() => false);
640532
+ } else {
640533
+ await this.answerCallbackQuery(callback.id).catch(() => false);
640534
+ }
640535
+ }
640536
+ }
640537
+ async sendOrEditFinalTelegramHTML(msg, html, liveMessageId, replyMarkup) {
640143
640538
  const chunks = splitTelegramMessageText(html, 3900);
640144
640539
  if (chunks.length === 0) return null;
640145
640540
  const replyToMessageId = msg.chatType !== "private" ? msg.messageId : void 0;
640146
640541
  const suppressMedia = this.deliveredArtifactMediaSuppressorForMessage(msg);
640147
640542
  if (liveMessageId && !msg.guestQueryId) {
640148
- const edited = await this.editLiveMessage(msg.chatId, liveMessageId, chunks[0]);
640543
+ const edited = await this.editLiveMessage(msg.chatId, liveMessageId, chunks[0], replyMarkup);
640149
640544
  if (edited) {
640150
640545
  for (const chunk of chunks.slice(1)) {
640151
640546
  await this.sendMessageHTML(msg.chatId, chunk, void 0, { suppressMedia });
@@ -640163,7 +640558,7 @@ ${summary}` : ""
640163
640558
  msg.chatId,
640164
640559
  chunks[idx],
640165
640560
  idx === 0 ? replyToMessageId : void 0,
640166
- { suppressMedia }
640561
+ { suppressMedia, ...idx === 0 && replyMarkup ? { replyMarkup } : {} }
640167
640562
  );
640168
640563
  if (firstMessageId === null) firstMessageId = messageId;
640169
640564
  }
@@ -640526,7 +640921,14 @@ Join: ${newUrl}`);
640526
640921
  });
640527
640922
  }
640528
640923
  const finalHtml = convertMarkdownToTelegramHTML(finalText);
640529
- const sentMessageId = isAdminDM && !msg.guestQueryId ? await this.finalizeTelegramAdminLivePanel(subAgent, msg, finalText, "completed") : await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId);
640924
+ const contextExplorerState = !isAdminDM && msg.chatType !== "private" && !msg.guestQueryId ? this.buildTelegramContextExplorerState(msg, subAgent, finalHtml, finalText) : null;
640925
+ const contextExplorerReplyMarkup = contextExplorerState ? this.telegramContextExplorerReplyMarkup(contextExplorerState.id) : void 0;
640926
+ const sentMessageId = isAdminDM && !msg.guestQueryId ? await this.finalizeTelegramAdminLivePanel(subAgent, msg, finalText, "completed") : await this.sendOrEditFinalTelegramHTML(msg, finalHtml, subAgent.liveMessageId, contextExplorerReplyMarkup);
640927
+ if (contextExplorerState && sentMessageId !== null) {
640928
+ this.pruneTelegramContextExplorers();
640929
+ contextExplorerState.messageId = sentMessageId;
640930
+ this.telegramContextExplorerStates.set(contextExplorerState.id, contextExplorerState);
640931
+ }
640530
640932
  if (sentMessageId !== null || msg.guestQueryId) {
640531
640933
  this.recordTelegramAssistantMessage(msg, finalText, subAgentProfile, {
640532
640934
  messageId: sentMessageId,
@@ -641066,6 +641468,7 @@ ${conversationStream}`
641066
641468
  modelTier,
641067
641469
  streamEnabled: true,
641068
641470
  dynamicContext: sessionContext.context,
641471
+ captureContextFrame: true,
641069
641472
  stateDir: runnerStateDir,
641070
641473
  sessionId: sessionContext.sessionId,
641071
641474
  disablePersistentMemory: false,
@@ -641110,6 +641513,9 @@ ${conversationStream}`
641110
641513
  runner.onEvent((event) => {
641111
641514
  if (subAgent.aborted) return;
641112
641515
  let suppressExternalEvent = false;
641516
+ if (event.contextFrame) {
641517
+ subAgent.contextFrame = event.contextFrame;
641518
+ }
641113
641519
  if (!isAdminDM && event.type === "status") {
641114
641520
  suppressExternalEvent = true;
641115
641521
  }
@@ -641287,6 +641693,24 @@ ${selfIdentityContext}
641287
641693
  Telegram ${isGroup ? "group" : "public"} chat. Respond concisely. Safety filter: active.${creativeWorkspace ? `
641288
641694
 
641289
641695
  ${creativeWorkspace}` : ""}`;
641696
+ subAgent.promptSnapshot = {
641697
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
641698
+ model: config.model,
641699
+ modelTier,
641700
+ toolContext: ctx3,
641701
+ profile,
641702
+ sessionKey: sessionContext.sessionKey,
641703
+ sessionId: sessionContext.sessionId,
641704
+ chatType: msg.chatType,
641705
+ ...msg.chatTitle ? { chatTitle: msg.chatTitle } : {},
641706
+ username: msg.username,
641707
+ toolNames: tools.map((tool) => tool.name),
641708
+ systemContext: systemCtx,
641709
+ taskPrompt: userPrompt,
641710
+ dynamicContext: sessionContext.context,
641711
+ mediaContext,
641712
+ additionalContext
641713
+ };
641290
641714
  const result = await runner.run(userPrompt, systemCtx);
641291
641715
  subAgent.runnerCompleted = result.completed;
641292
641716
  subAgent.runnerTurns = result.turns;
@@ -643221,26 +643645,34 @@ Scoped workspace: ${scopedRoot}`,
643221
643645
  return;
643222
643646
  }
643223
643647
  const parts = callback.data.split(":");
643224
- if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgadmin" || parts[4] !== "page") {
643648
+ if (parts.length !== 6 || parts[0] !== "omni" || parts[1] !== "v1" || parts[2] !== "tgadmin" || parts[4] !== "page" && parts[4] !== "ctx") {
643225
643649
  answerText2 = "Unknown Omnius admin panel control.";
643226
643650
  alert2 = true;
643227
643651
  return;
643228
643652
  }
643229
643653
  this.pruneTelegramAdminLivePanels();
643230
643654
  const state = this.telegramAdminLivePanels.get(parts[3] ?? "");
643231
- const page2 = parts[5];
643232
643655
  if (!state || state.expiresAt < Date.now()) {
643233
643656
  answerText2 = "This admin run panel expired.";
643234
643657
  alert2 = true;
643235
643658
  return;
643236
643659
  }
643237
- if (!page2 || !TELEGRAM_ADMIN_LIVE_PANEL_PAGES.includes(page2)) {
643238
- answerText2 = "Unknown admin run page.";
643239
- alert2 = true;
643240
- return;
643660
+ if (parts[4] === "ctx") {
643661
+ const requestedPage = Number.parseInt(parts[5] ?? "0", 10);
643662
+ const lastPage = Math.max(0, state.contextPages.length - 1);
643663
+ state.activePage = "context";
643664
+ state.contextPageIndex = Number.isFinite(requestedPage) ? Math.min(lastPage, Math.max(0, requestedPage)) : 0;
643665
+ state.dirtyPages.context = false;
643666
+ } else {
643667
+ const page2 = parts[5];
643668
+ if (!page2 || !TELEGRAM_ADMIN_LIVE_PANEL_PAGES.includes(page2)) {
643669
+ answerText2 = "Unknown admin run page.";
643670
+ alert2 = true;
643671
+ return;
643672
+ }
643673
+ state.activePage = page2;
643674
+ state.dirtyPages[page2] = false;
643241
643675
  }
643242
- state.activePage = page2;
643243
- state.dirtyPages[page2] = false;
643244
643676
  const messageId = state.messageId ?? callback.messageId;
643245
643677
  if (messageId === void 0) {
643246
643678
  answerText2 = "Cannot identify panel message.";
@@ -643262,6 +643694,10 @@ Scoped workspace: ${scopedRoot}`,
643262
643694
  }
643263
643695
  return;
643264
643696
  }
643697
+ if (callback.data.startsWith("omni:v1:tgctx:")) {
643698
+ await this.handleTelegramContextExplorerCallback(callback);
643699
+ return;
643700
+ }
643265
643701
  let answerText = "Updated.";
643266
643702
  let alert = false;
643267
643703
  try {
@@ -644009,6 +644445,7 @@ ${text}`.trim());
644009
644445
  };
644010
644446
  const replyParameters = idx === 0 ? telegramReplyParameters(replyToMessageId) : void 0;
644011
644447
  if (replyParameters) body["reply_parameters"] = replyParameters;
644448
+ if (idx === 0 && options2.replyMarkup) body["reply_markup"] = options2.replyMarkup;
644012
644449
  const sessionKeyForObs = String(chatId);
644013
644450
  try {
644014
644451
  const result = await this.apiCall("sendMessage", body);
@@ -644030,6 +644467,7 @@ ${text}`.trim());
644030
644467
  const plain = chunk.replace(/<[^>]+>/g, "");
644031
644468
  const fallbackBody = { chat_id: chatId, text: plain };
644032
644469
  if (replyParameters) fallbackBody["reply_parameters"] = replyParameters;
644470
+ if (idx === 0 && options2.replyMarkup) fallbackBody["reply_markup"] = options2.replyMarkup;
644033
644471
  try {
644034
644472
  const result = await this.apiCall("sendMessage", fallbackBody);
644035
644473
  if (result.ok === false) throw new Error(String(result.description || "Telegram sendMessage failed"));
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.191",
3
+ "version": "1.0.192",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.191",
9
+ "version": "1.0.192",
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.191",
3
+ "version": "1.0.192",
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",