omnius 1.0.333 → 1.0.335
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 +265 -37
- package/npm-shrinkwrap.json +5 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -279541,19 +279541,26 @@ import { execFileSync as execFileSync6 } from "node:child_process";
|
|
|
279541
279541
|
import { existsSync as existsSync42, readFileSync as readFileSync31, writeFileSync as writeFileSync21, mkdirSync as mkdirSync23, statfsSync as statfsSync3 } from "node:fs";
|
|
279542
279542
|
import { join as join51 } from "node:path";
|
|
279543
279543
|
import { cpus, totalmem as totalmem2 } from "node:os";
|
|
279544
|
+
function gpuComputeUsable(computeCap) {
|
|
279545
|
+
if (!computeCap)
|
|
279546
|
+
return true;
|
|
279547
|
+
const v = parseFloat(computeCap);
|
|
279548
|
+
return Number.isFinite(v) ? v >= MIN_COMPUTE_CAP : true;
|
|
279549
|
+
}
|
|
279544
279550
|
function bytesToGiB(bytes) {
|
|
279545
279551
|
return Math.round(bytes / 1024 ** 3 * 10) / 10;
|
|
279546
279552
|
}
|
|
279547
279553
|
function probeGpus() {
|
|
279548
279554
|
try {
|
|
279549
|
-
const out = execFileSync6("nvidia-smi", ["--query-gpu=index,name,memory.total,memory.free", "--format=csv,noheader,nounits"], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
279555
|
+
const out = execFileSync6("nvidia-smi", ["--query-gpu=index,name,memory.total,memory.free,compute_cap", "--format=csv,noheader,nounits"], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
279550
279556
|
return out.trim().split("\n").map((line) => {
|
|
279551
|
-
const [index, name10, total, free] = line.split(",").map((s2) => s2.trim());
|
|
279557
|
+
const [index, name10, total, free, cap] = line.split(",").map((s2) => s2.trim());
|
|
279552
279558
|
return {
|
|
279553
279559
|
index: parseInt(index || "0", 10),
|
|
279554
279560
|
name: name10 || "GPU",
|
|
279555
279561
|
memTotalMiB: parseInt(total || "0", 10),
|
|
279556
|
-
memFreeMiB: parseInt(free || "0", 10)
|
|
279562
|
+
memFreeMiB: parseInt(free || "0", 10),
|
|
279563
|
+
computeCap: cap || ""
|
|
279557
279564
|
};
|
|
279558
279565
|
}).filter((g) => Number.isFinite(g.memTotalMiB) && g.memTotalMiB > 0);
|
|
279559
279566
|
} catch {
|
|
@@ -279577,9 +279584,10 @@ function diskFreeGiB(path12) {
|
|
|
279577
279584
|
}
|
|
279578
279585
|
}
|
|
279579
279586
|
function selectStack(facts) {
|
|
279580
|
-
const usable = facts.gpus.filter((g) => g.memTotalMiB >= USABLE_GPU_MIN_MIB);
|
|
279587
|
+
const usable = facts.gpus.filter((g) => g.memTotalMiB >= USABLE_GPU_MIN_MIB && gpuComputeUsable(g.computeCap));
|
|
279581
279588
|
const maxVramGiB = usable.length > 0 ? Math.round(Math.max(...usable.map((g) => g.memTotalMiB)) / 1024) : 0;
|
|
279582
279589
|
const gpuCount = usable.length;
|
|
279590
|
+
const cudaVisibleDevices = usable.map((g) => g.index).join(",");
|
|
279583
279591
|
if (gpuCount === 0) {
|
|
279584
279592
|
return {
|
|
279585
279593
|
stack: "edge",
|
|
@@ -279587,7 +279595,8 @@ function selectStack(facts) {
|
|
|
279587
279595
|
precision: "fp32",
|
|
279588
279596
|
vramGiB: 0,
|
|
279589
279597
|
gpuCount: 0,
|
|
279590
|
-
|
|
279598
|
+
cudaVisibleDevices: "",
|
|
279599
|
+
reason: `No usable GPU (>=8 GiB, compute>=7.0) detected; CPU edge stack on ${facts.cpuCores} cores / ${facts.ramGiB} GiB RAM.`
|
|
279591
279600
|
};
|
|
279592
279601
|
}
|
|
279593
279602
|
const precision = maxVramGiB >= 24 ? "bf16" : "fp16";
|
|
@@ -279598,7 +279607,8 @@ function selectStack(facts) {
|
|
|
279598
279607
|
precision,
|
|
279599
279608
|
vramGiB: maxVramGiB,
|
|
279600
279609
|
gpuCount,
|
|
279601
|
-
|
|
279610
|
+
cudaVisibleDevices,
|
|
279611
|
+
reason: `Forensic stack: ${gpuCount} usable GPU(s) [${cudaVisibleDevices}], max ${maxVramGiB} GiB VRAM — multi-pass + thinking-variant LALM + high-res reinspection.`
|
|
279602
279612
|
};
|
|
279603
279613
|
}
|
|
279604
279614
|
if (maxVramGiB >= 16) {
|
|
@@ -279608,7 +279618,8 @@ function selectStack(facts) {
|
|
|
279608
279618
|
precision,
|
|
279609
279619
|
vramGiB: maxVramGiB,
|
|
279610
279620
|
gpuCount,
|
|
279611
|
-
|
|
279621
|
+
cudaVisibleDevices,
|
|
279622
|
+
reason: `Baseline stack: one ${maxVramGiB} GiB GPU [${cudaVisibleDevices}] — V-JEPA2-L/VideoPrism + YOLOE+SAM2 + event-triggered 7B VLM/LALM.`
|
|
279612
279623
|
};
|
|
279613
279624
|
}
|
|
279614
279625
|
return {
|
|
@@ -279617,7 +279628,8 @@ function selectStack(facts) {
|
|
|
279617
279628
|
precision,
|
|
279618
279629
|
vramGiB: maxVramGiB,
|
|
279619
279630
|
gpuCount,
|
|
279620
|
-
|
|
279631
|
+
cudaVisibleDevices,
|
|
279632
|
+
reason: `Edge stack on GPU [${cudaVisibleDevices}]: only ${maxVramGiB} GiB VRAM — keyframe detectors + lite encoders, small models on event windows.`
|
|
279621
279633
|
};
|
|
279622
279634
|
}
|
|
279623
279635
|
function adapterPlacement(cap, role) {
|
|
@@ -279664,11 +279676,12 @@ function getMediaCapability(opts = {}) {
|
|
|
279664
279676
|
}
|
|
279665
279677
|
return cap;
|
|
279666
279678
|
}
|
|
279667
|
-
var USABLE_GPU_MIN_MIB, CACHE_FILE2, CACHE_TTL_MS2;
|
|
279679
|
+
var MIN_COMPUTE_CAP, USABLE_GPU_MIN_MIB, CACHE_FILE2, CACHE_TTL_MS2;
|
|
279668
279680
|
var init_media_capability = __esm({
|
|
279669
279681
|
"packages/execution/dist/av/media-capability.js"() {
|
|
279670
279682
|
"use strict";
|
|
279671
279683
|
init_model_store();
|
|
279684
|
+
MIN_COMPUTE_CAP = 7;
|
|
279672
279685
|
USABLE_GPU_MIN_MIB = 8 * 1024;
|
|
279673
279686
|
CACHE_FILE2 = "av-capability.json";
|
|
279674
279687
|
CACHE_TTL_MS2 = 60 * 60 * 1e3;
|
|
@@ -553530,6 +553543,7 @@ __export(dist_exports2, {
|
|
|
553530
553543
|
gigabytesToBytes: () => gigabytesToBytes,
|
|
553531
553544
|
globalMediaDir: () => globalMediaDir,
|
|
553532
553545
|
globalMediaRootDir: () => globalMediaRootDir,
|
|
553546
|
+
gpuComputeUsable: () => gpuComputeUsable,
|
|
553533
553547
|
hasMaterialAmbiguity: () => hasMaterialAmbiguity,
|
|
553534
553548
|
hashGeneratedArtifactContent: () => hashGeneratedArtifactContent,
|
|
553535
553549
|
hashProcessCommand: () => hashProcessCommand,
|
|
@@ -599722,8 +599736,8 @@ function codePreviewLines(output, maxLines) {
|
|
|
599722
599736
|
return [{ text: "(empty file)", mode: "wrap", kind: "dim" }];
|
|
599723
599737
|
let hlLines = null;
|
|
599724
599738
|
if (isAvailable()) {
|
|
599725
|
-
const
|
|
599726
|
-
const hl = highlightBlock(
|
|
599739
|
+
const codeBlock2 = shown.join("\n");
|
|
599740
|
+
const hl = highlightBlock(codeBlock2);
|
|
599727
599741
|
if (hl.length === shown.length) hlLines = hl;
|
|
599728
599742
|
}
|
|
599729
599743
|
const body = shown.map((line, i2) => ({
|
|
@@ -610144,6 +610158,34 @@ var init_status_bar = __esm({
|
|
|
610144
610158
|
unregisterDynamicBlock(id) {
|
|
610145
610159
|
this._dynamicBlocks.delete(id);
|
|
610146
610160
|
}
|
|
610161
|
+
/**
|
|
610162
|
+
* Expand every dynamic-block sentinel in `lines` into its registered render
|
|
610163
|
+
* output. Used at SESSION-SAVE time so the persisted transcript carries the
|
|
610164
|
+
* REAL tool / shell / task-complete content instead of `\x01DYNBLOCK:<id>\x01`
|
|
610165
|
+
* sentinels whose content otherwise lives only in this in-memory store and is
|
|
610166
|
+
* lost on reload. Stale/unknown sentinels are dropped (not left as dead
|
|
610167
|
+
* markers). ANSI is stripped by the persistence layer afterwards.
|
|
610168
|
+
*/
|
|
610169
|
+
expandDynamicBlockSentinels(lines, width = 100) {
|
|
610170
|
+
const out = [];
|
|
610171
|
+
for (const line of lines) {
|
|
610172
|
+
if (typeof line === "string" && line.startsWith(this.DYNAMIC_BLOCK_MARK_PREFIX) && line.endsWith(this.DYNAMIC_BLOCK_MARK_SUFFIX) && line.length > this.DYNAMIC_BLOCK_MARK_PREFIX.length + this.DYNAMIC_BLOCK_MARK_SUFFIX.length) {
|
|
610173
|
+
const id = line.slice(
|
|
610174
|
+
this.DYNAMIC_BLOCK_MARK_PREFIX.length,
|
|
610175
|
+
line.length - this.DYNAMIC_BLOCK_MARK_SUFFIX.length
|
|
610176
|
+
);
|
|
610177
|
+
const renderer = this._dynamicBlocks.get(id);
|
|
610178
|
+
if (!renderer) continue;
|
|
610179
|
+
try {
|
|
610180
|
+
for (const seg of renderer(width)) out.push(seg);
|
|
610181
|
+
} catch {
|
|
610182
|
+
}
|
|
610183
|
+
} else {
|
|
610184
|
+
out.push(line);
|
|
610185
|
+
}
|
|
610186
|
+
}
|
|
610187
|
+
return out;
|
|
610188
|
+
}
|
|
610147
610189
|
/**
|
|
610148
610190
|
* Append a previously-registered dynamic block's sentinel to scrollback
|
|
610149
610191
|
* and trigger a repaint. The block's renderer fires immediately at the
|
|
@@ -654909,6 +654951,140 @@ var init_emotion_engine = __esm({
|
|
|
654909
654951
|
}
|
|
654910
654952
|
});
|
|
654911
654953
|
|
|
654954
|
+
// packages/cli/src/tui/telegram-format.ts
|
|
654955
|
+
function escapeHtml2(text2) {
|
|
654956
|
+
return String(text2 ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
654957
|
+
}
|
|
654958
|
+
function toolCallBlock(name10, args) {
|
|
654959
|
+
const header = `<b>Tool call</b> <code>${escapeHtml2(name10 || "tool")}</code>`;
|
|
654960
|
+
if (args == null || typeof args === "object" && Object.keys(args).length === 0) {
|
|
654961
|
+
return header;
|
|
654962
|
+
}
|
|
654963
|
+
const compact3 = typeof args === "string" ? args : safeJson(args, false);
|
|
654964
|
+
if (compact3.length <= 120 && !compact3.includes("\n")) {
|
|
654965
|
+
return `${header} <code>${escapeHtml2(compact3)}</code>`;
|
|
654966
|
+
}
|
|
654967
|
+
const pretty = typeof args === "string" ? args : safeJson(args, true);
|
|
654968
|
+
return `${header}
|
|
654969
|
+
${codeBlock(pretty, "json")}`;
|
|
654970
|
+
}
|
|
654971
|
+
function toolResultBlock(name10, ok3, output) {
|
|
654972
|
+
const header = `<b>Tool result</b> <code>${escapeHtml2(name10 || "tool")}</code>`;
|
|
654973
|
+
const body = String(output ?? "").trim();
|
|
654974
|
+
if (!body) return `${header}
|
|
654975
|
+
<i>${ok3 ? "completed" : "failed"}</i>`;
|
|
654976
|
+
if (body.length <= 160 && !body.includes("\n")) {
|
|
654977
|
+
return `${header}
|
|
654978
|
+
<blockquote>${escapeHtml2(body)}</blockquote>`;
|
|
654979
|
+
}
|
|
654980
|
+
return `${header}
|
|
654981
|
+
<blockquote expandable>${escapeHtml2(body)}</blockquote>`;
|
|
654982
|
+
}
|
|
654983
|
+
function codeBlock(code8, language = "") {
|
|
654984
|
+
const inner = escapeHtml2(String(code8 ?? "").replace(/\s+$/, ""));
|
|
654985
|
+
return language ? `<pre><code class="language-${escapeHtml2(language)}">${inner}</code></pre>` : `<pre>${inner}</pre>`;
|
|
654986
|
+
}
|
|
654987
|
+
function safeJson(v, pretty) {
|
|
654988
|
+
try {
|
|
654989
|
+
return pretty ? JSON.stringify(v, null, 2) : JSON.stringify(v);
|
|
654990
|
+
} catch {
|
|
654991
|
+
return String(v);
|
|
654992
|
+
}
|
|
654993
|
+
}
|
|
654994
|
+
function tokenizeTelegramHtml(html) {
|
|
654995
|
+
const tokens = [];
|
|
654996
|
+
const re = /<(\/?)([a-zA-Z][\w-]*)((?:\s[^>]*)?)>/g;
|
|
654997
|
+
let last2 = 0;
|
|
654998
|
+
let m2;
|
|
654999
|
+
while ((m2 = re.exec(html)) !== null) {
|
|
655000
|
+
if (m2.index > last2) tokens.push({ type: "text", raw: html.slice(last2, m2.index) });
|
|
655001
|
+
const closing = m2[1] === "/";
|
|
655002
|
+
const tag = (m2[2] || "").toLowerCase();
|
|
655003
|
+
if (SPAN_TAGS.has(tag)) {
|
|
655004
|
+
tokens.push(closing ? { type: "close", tag, raw: m2[0] } : { type: "open", tag, raw: m2[0] });
|
|
655005
|
+
} else {
|
|
655006
|
+
tokens.push({ type: "text", raw: m2[0] });
|
|
655007
|
+
}
|
|
655008
|
+
last2 = re.lastIndex;
|
|
655009
|
+
}
|
|
655010
|
+
if (last2 < html.length) tokens.push({ type: "text", raw: html.slice(last2) });
|
|
655011
|
+
return tokens;
|
|
655012
|
+
}
|
|
655013
|
+
function segmentTelegramHtml(html, maxLength = SAFE_LIMIT) {
|
|
655014
|
+
const text2 = String(html ?? "");
|
|
655015
|
+
if (text2.length <= maxLength) return text2.trim() ? [text2] : [];
|
|
655016
|
+
const tokens = tokenizeTelegramHtml(text2);
|
|
655017
|
+
const out = [];
|
|
655018
|
+
let cur = "";
|
|
655019
|
+
const stack = [];
|
|
655020
|
+
const closeAll = () => stack.slice().reverse().map((t2) => `</${t2.tag}>`).join("");
|
|
655021
|
+
const reopen = () => stack.map((t2) => t2.raw).join("");
|
|
655022
|
+
const closeLen = () => stack.reduce((n2, t2) => n2 + t2.tag.length + 3, 0);
|
|
655023
|
+
const flush3 = () => {
|
|
655024
|
+
const finished = cur + closeAll();
|
|
655025
|
+
if (finished.trim()) out.push(finished);
|
|
655026
|
+
cur = reopen();
|
|
655027
|
+
};
|
|
655028
|
+
for (const tok of tokens) {
|
|
655029
|
+
if (tok.type === "open") {
|
|
655030
|
+
if (cur.length + tok.raw.length + closeLen() > maxLength) flush3();
|
|
655031
|
+
cur += tok.raw;
|
|
655032
|
+
stack.push({ tag: tok.tag, raw: tok.raw });
|
|
655033
|
+
} else if (tok.type === "close") {
|
|
655034
|
+
cur += tok.raw;
|
|
655035
|
+
for (let i2 = stack.length - 1; i2 >= 0; i2--) {
|
|
655036
|
+
if (stack[i2].tag === tok.tag) {
|
|
655037
|
+
stack.splice(i2, 1);
|
|
655038
|
+
break;
|
|
655039
|
+
}
|
|
655040
|
+
}
|
|
655041
|
+
} else {
|
|
655042
|
+
let body = tok.raw;
|
|
655043
|
+
while (cur.length + body.length + closeLen() > maxLength) {
|
|
655044
|
+
const room = maxLength - cur.length - closeLen();
|
|
655045
|
+
if (room <= 1) {
|
|
655046
|
+
flush3();
|
|
655047
|
+
continue;
|
|
655048
|
+
}
|
|
655049
|
+
let bp = body.lastIndexOf("\n", room);
|
|
655050
|
+
if (bp < room * 0.5) bp = body.lastIndexOf(" ", room);
|
|
655051
|
+
if (bp < room * 0.5) bp = room;
|
|
655052
|
+
cur += body.slice(0, bp);
|
|
655053
|
+
flush3();
|
|
655054
|
+
body = body.slice(bp).replace(/^\s+/, "");
|
|
655055
|
+
}
|
|
655056
|
+
cur += body;
|
|
655057
|
+
}
|
|
655058
|
+
}
|
|
655059
|
+
const tail = cur + closeAll();
|
|
655060
|
+
if (tail.trim()) out.push(tail);
|
|
655061
|
+
return out;
|
|
655062
|
+
}
|
|
655063
|
+
var SAFE_LIMIT, SPAN_TAGS;
|
|
655064
|
+
var init_telegram_format = __esm({
|
|
655065
|
+
"packages/cli/src/tui/telegram-format.ts"() {
|
|
655066
|
+
"use strict";
|
|
655067
|
+
SAFE_LIMIT = 3900;
|
|
655068
|
+
SPAN_TAGS = /* @__PURE__ */ new Set([
|
|
655069
|
+
"b",
|
|
655070
|
+
"strong",
|
|
655071
|
+
"i",
|
|
655072
|
+
"em",
|
|
655073
|
+
"u",
|
|
655074
|
+
"ins",
|
|
655075
|
+
"s",
|
|
655076
|
+
"strike",
|
|
655077
|
+
"del",
|
|
655078
|
+
"code",
|
|
655079
|
+
"pre",
|
|
655080
|
+
"blockquote",
|
|
655081
|
+
"tg-spoiler",
|
|
655082
|
+
"a",
|
|
655083
|
+
"span"
|
|
655084
|
+
]);
|
|
655085
|
+
}
|
|
655086
|
+
});
|
|
655087
|
+
|
|
654912
655088
|
// packages/cli/src/tui/tool-policy.ts
|
|
654913
655089
|
function getDefaultPolicy(context2) {
|
|
654914
655090
|
switch (context2) {
|
|
@@ -660540,8 +660716,8 @@ function convertMarkdownToTelegramHTML(md) {
|
|
|
660540
660716
|
let html = normalizeTelegramOutboundLinks(md);
|
|
660541
660717
|
html = html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
660542
660718
|
html = html.replace(
|
|
660543
|
-
/```[\w]
|
|
660544
|
-
(_m, code8) => `<pre>${code8.trimEnd()}</pre>`
|
|
660719
|
+
/```([\w+-]*)\n?([\s\S]*?)```/g,
|
|
660720
|
+
(_m, lang, code8) => lang ? `<pre><code class="language-${lang}">${code8.trimEnd()}</code></pre>` : `<pre>${code8.trimEnd()}</pre>`
|
|
660545
660721
|
);
|
|
660546
660722
|
html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
|
|
660547
660723
|
html = html.replace(/\*\*(.+?)\*\*/g, "<b>$1</b>");
|
|
@@ -660590,6 +660766,9 @@ function truncateTelegramUrlSafe(text2, maxLength, suffix = "...") {
|
|
|
660590
660766
|
function splitTelegramMessageText(text2, maxLength = 3900) {
|
|
660591
660767
|
const trimmed = text2.trim();
|
|
660592
660768
|
if (!trimmed) return [];
|
|
660769
|
+
if (/<\/?[a-zA-Z][\w-]*(?:\s[^>]*)?>/.test(trimmed)) {
|
|
660770
|
+
return segmentTelegramHtml(trimmed, maxLength);
|
|
660771
|
+
}
|
|
660593
660772
|
const chunks = [];
|
|
660594
660773
|
let remaining = trimmed;
|
|
660595
660774
|
while (remaining.length > maxLength) {
|
|
@@ -661038,20 +661217,12 @@ function formatTelegramProgressEvent(event) {
|
|
|
661038
661217
|
if (event.type === "tool_result" && event.toolName === "task_complete")
|
|
661039
661218
|
return null;
|
|
661040
661219
|
if (event.type === "tool_call") {
|
|
661041
|
-
return
|
|
661220
|
+
return toolCallBlock(event.toolName || "tool");
|
|
661042
661221
|
}
|
|
661043
661222
|
if (event.type === "tool_result") {
|
|
661044
|
-
const preview = sanitizeTelegramProgressText(event.content || "",
|
|
661223
|
+
const preview = sanitizeTelegramProgressText(event.content || "", 1500);
|
|
661045
661224
|
if (isTelegramInternalStatusText(preview)) return null;
|
|
661046
|
-
|
|
661047
|
-
if (preview) {
|
|
661048
|
-
return [
|
|
661049
|
-
`<b>Tool result</b> <code>${toolName}</code>`,
|
|
661050
|
-
`<blockquote>${escapeTelegramHTML(preview)}</blockquote>`
|
|
661051
|
-
].join("\n");
|
|
661052
|
-
}
|
|
661053
|
-
return `<b>Tool result</b> <code>${toolName}</code>
|
|
661054
|
-
<i>${event.success ? "completed" : "failed"}</i>`;
|
|
661225
|
+
return toolResultBlock(event.toolName || "tool", Boolean(event.success), preview);
|
|
661055
661226
|
}
|
|
661056
661227
|
if (event.type === "status") {
|
|
661057
661228
|
if (isCodebaseMemoryStatus(event.content || "")) {
|
|
@@ -662165,6 +662336,7 @@ var TELEGRAM_TOOL_ACTION_GROUPS, TELEGRAM_TOOL_ACTION_GROUP, TELEGRAM_TOOL_MUTAT
|
|
|
662165
662336
|
var init_telegram_bridge = __esm({
|
|
662166
662337
|
"packages/cli/src/tui/telegram-bridge.ts"() {
|
|
662167
662338
|
"use strict";
|
|
662339
|
+
init_telegram_format();
|
|
662168
662340
|
init_dist8();
|
|
662169
662341
|
init_dist5();
|
|
662170
662342
|
init_project_context();
|
|
@@ -693946,6 +694118,64 @@ window.refreshTodos = refreshTodos;
|
|
|
693946
694118
|
// own process group)
|
|
693947
694119
|
// - Frontend re-attaches via this restore path and shows the partial
|
|
693948
694120
|
// output via partial_output_tail in the in_flight payload
|
|
694121
|
+
// Parse a raw rendered-TUI transcript into clean GUI chat bubbles. Strips the
|
|
694122
|
+
// DYNBLOCK:<id> sentinels (no content in the persisted log) and TUI
|
|
694123
|
+
// chrome, then emits user (▹/>) and assistant (│) messages.
|
|
694124
|
+
function renderRecoveredTranscript(raw, conv, title) {
|
|
694125
|
+
const SOH = String.fromCharCode(1);
|
|
694126
|
+
const NL = String.fromCharCode(10);
|
|
694127
|
+
const sentRe = new RegExp(SOH + 'DYNBLOCK:[^' + SOH + ']*' + SOH, 'g');
|
|
694128
|
+
const lines = String(raw).replace(new RegExp(String.fromCharCode(13), 'g'), '').split(NL);
|
|
694129
|
+
let mode = null; // 'user' | 'assistant'
|
|
694130
|
+
let buf = [];
|
|
694131
|
+
let toolCount = 0;
|
|
694132
|
+
const out = []; // [{role, text}] or {tools:n}
|
|
694133
|
+
const flush = () => {
|
|
694134
|
+
const text = buf.join(NL).trim();
|
|
694135
|
+
if (text && mode) out.push({ role: mode, text: text });
|
|
694136
|
+
buf = [];
|
|
694137
|
+
};
|
|
694138
|
+
for (let line of lines) {
|
|
694139
|
+
// Count + drop dynamic-block sentinels (tool/shell/etc. — their content is
|
|
694140
|
+
// not in the log; surface them as a compact "tool activity" marker).
|
|
694141
|
+
const sentinels = (line.match(sentRe) || []).length;
|
|
694142
|
+
if (sentinels) toolCount += sentinels;
|
|
694143
|
+
line = line.replace(sentRe, '');
|
|
694144
|
+
const t = line.trim();
|
|
694145
|
+
if (!t) continue;
|
|
694146
|
+
// Skip pure box-border lines from expanded tool/task boxes (╭─╮ ╰─╯ etc.).
|
|
694147
|
+
if (/^[─-╿s]+$/.test(t)) continue;
|
|
694148
|
+
if (/^[▹>]s?/.test(t)) { // user prompt
|
|
694149
|
+
flush(); if (toolCount) { out.push({ tools: toolCount }); toolCount = 0; }
|
|
694150
|
+
out.push({ role: 'user', text: t.replace(/^[▹>]s?/, '') }); mode = null; continue;
|
|
694151
|
+
}
|
|
694152
|
+
if (/^│/.test(t)) { // assistant / box content
|
|
694153
|
+
if (mode !== 'assistant') { flush(); mode = 'assistant'; }
|
|
694154
|
+
buf.push(t.replace(/^│s?/, '').replace(/s?│$/, '')); continue; // strip both borders
|
|
694155
|
+
}
|
|
694156
|
+
if (/^[∙!]/.test(t)) continue; // status / internal noise — drop
|
|
694157
|
+
if (mode === 'assistant') buf.push(t); // continuation
|
|
694158
|
+
}
|
|
694159
|
+
flush(); if (toolCount) out.push({ tools: toolCount });
|
|
694160
|
+
|
|
694161
|
+
if (out.length === 0) return; // nothing meaningful — show nothing rather than garbage
|
|
694162
|
+
const note = document.createElement('div');
|
|
694163
|
+
note.style.cssText = 'font-size:0.6rem;color:var(--color-fg-faint);margin:4px 0 8px;text-align:center';
|
|
694164
|
+
note.textContent = 'recovered session' + (title ? ' — ' + title : '');
|
|
694165
|
+
conv.appendChild(note);
|
|
694166
|
+
for (const item of out) {
|
|
694167
|
+
if (item.tools) {
|
|
694168
|
+
const td = document.createElement('div');
|
|
694169
|
+
td.style.cssText = 'font-size:0.6rem;color:var(--color-fg-faint);margin:2px 0 6px;padding-left:8px';
|
|
694170
|
+
td.textContent = '⚙ ' + item.tools + ' tool action' + (item.tools === 1 ? '' : 's');
|
|
694171
|
+
conv.appendChild(td);
|
|
694172
|
+
} else {
|
|
694173
|
+
addMessage(item.role, item.text);
|
|
694174
|
+
}
|
|
694175
|
+
}
|
|
694176
|
+
}
|
|
694177
|
+
window.renderRecoveredTranscript = renderRecoveredTranscript;
|
|
694178
|
+
|
|
693949
694179
|
async function restoreChatSession() {
|
|
693950
694180
|
// chatSessionId is the window-property shim → $chatSessionId.get().
|
|
693951
694181
|
// Project-scoped storage already hydrated this on $currentProject.set,
|
|
@@ -693982,18 +694212,15 @@ async function restoreChatSession() {
|
|
|
693982
694212
|
// decisions, sub-agent activity — everything that scrolled past in the
|
|
693983
694213
|
// TUI) as a visible, scrollable block at the top so opening the session
|
|
693984
694214
|
// actually shows what happened, instead of just a "loaded" notice.
|
|
693985
|
-
if (data.transcript && String(data.transcript).trim() && data.transcript !== '(empty transcript)'
|
|
693986
|
-
|
|
693987
|
-
|
|
693988
|
-
|
|
693989
|
-
|
|
693990
|
-
|
|
693991
|
-
|
|
693992
|
-
|
|
693993
|
-
|
|
693994
|
-
wrap.appendChild(head);
|
|
693995
|
-
wrap.appendChild(pre);
|
|
693996
|
-
conv.appendChild(wrap);
|
|
694215
|
+
if (data.transcript && String(data.transcript).trim() && data.transcript !== '(empty transcript)'
|
|
694216
|
+
&& (!allMessages || allMessages.length === 0)) {
|
|
694217
|
+
// TUI/raw transcript: PARSE the rendered-TUI scrollback into real chat
|
|
694218
|
+
// bubbles instead of dumping the raw log. The persisted log carries
|
|
694219
|
+
// DYNBLOCK:<id> sentinels (dynamic blocks expanded only at TUI
|
|
694220
|
+
// paint time — no content here) plus chrome (▹ user, │ assistant,
|
|
694221
|
+
// ∙ status, ! internal). We strip the dead sentinels + noise and emit
|
|
694222
|
+
// user/assistant messages so it reads like a GUI chat.
|
|
694223
|
+
renderRecoveredTranscript(String(data.transcript), conv, data.title || '');
|
|
693997
694224
|
}
|
|
693998
694225
|
// WO-CHAT-RESUME-TOOLS — replay the FULL intermediate flow on
|
|
693999
694226
|
// restore: user/assistant text bubbles AND tool_call/tool_result
|
|
@@ -711978,7 +712205,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
|
|
|
711978
712205
|
}
|
|
711979
712206
|
try {
|
|
711980
712207
|
const historySessionId = process.env["OMNIUS_SESSION_ID"] || `session-${Date.now().toString(36)}`;
|
|
711981
|
-
const
|
|
712208
|
+
const rawContentLines = statusBar?._contentLines ?? [];
|
|
712209
|
+
const contentLines = typeof statusBar?.expandDynamicBlockSentinels === "function" ? statusBar.expandDynamicBlockSentinels(rawContentLines, 100) : rawContentLines;
|
|
711982
712210
|
if (contentLines.length > 0) {
|
|
711983
712211
|
const description = cleanPromptForDiary(task).slice(0, 240);
|
|
711984
712212
|
const historyTitle = description.slice(0, 80) || void 0;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.335",
|
|
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.335",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
|
@@ -3986,9 +3986,9 @@
|
|
|
3986
3986
|
}
|
|
3987
3987
|
},
|
|
3988
3988
|
"node_modules/hono": {
|
|
3989
|
-
"version": "4.12.
|
|
3990
|
-
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.
|
|
3991
|
-
"integrity": "sha512-
|
|
3989
|
+
"version": "4.12.27",
|
|
3990
|
+
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.27.tgz",
|
|
3991
|
+
"integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q==",
|
|
3992
3992
|
"license": "MIT",
|
|
3993
3993
|
"engines": {
|
|
3994
3994
|
"node": ">=16.9.0"
|
package/package.json
CHANGED