omnius 1.0.335 → 1.0.336

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
@@ -555501,8 +555501,8 @@ var init_registry2 = __esm({
555501
555501
  PluginContextImpl = class {
555502
555502
  _registry;
555503
555503
  _manifest;
555504
- constructor(_registry5, _manifest) {
555505
- this._registry = _registry5;
555504
+ constructor(_registry6, _manifest) {
555505
+ this._registry = _registry6;
555506
555506
  this._manifest = _manifest;
555507
555507
  }
555508
555508
  get manifest() {
@@ -607196,7 +607196,7 @@ function cleanSessionHistoryDisplayLine(line) {
607196
607196
  function isNoisySessionHistoryLine(line) {
607197
607197
  const clean5 = cleanSessionHistoryDisplayLine(line || "");
607198
607198
  if (!clean5) return true;
607199
- return /^(?:Previous session found|REST API:|Nexus P2P network connected|No context to restore|Starting fresh|Use \/endpoint|Knowledge graph:|Zettelkasten:|Episodes captured:|Current OMNIUS_HOST:|Loaded TUI session|General session$|Chat tui:sess|i\s+)/i.test(clean5);
607199
+ return /^(?:Previous session found|REST API:|Nexus P2P network connected|No context to restore|Starting fresh|Use \/endpoint|Knowledge graph:|Zettelkasten:|Episodes captured:|Current OMNIUS_HOST:|Loaded TUI session|General session$|Chat tui:sess|TUI session\b|Using (?:expanded )?context model|Using model|Context (?:auto-)?restored|Context restored|Recovered session|Last task:|\(manual save\)|\[VRAM|VRAM |model_info|KV |arch[ -]capped|i\s+)/i.test(clean5);
607200
607200
  }
607201
607201
  function firstMeaningfulSessionHistoryLine(lines) {
607202
607202
  for (const line of lines) {
@@ -607576,18 +607576,17 @@ var init_omnius_directory = __esm({
607576
607576
  function isNoiseLine(line) {
607577
607577
  const t2 = line.trim();
607578
607578
  if (t2.length < 3) return true;
607579
- const core = t2.replace(/^[∙•·›>\-=_*#|/\\.\s]+/, "").trim();
607579
+ const core = t2.replace(TUI_MARKER_PREFIX, "").trim();
607580
607580
  if (core.length < 3) return true;
607581
- return /^(nexus|rest api|voice feedback|clone ref|connecting to|connected|http:\/\/|https:\/\/|last task:|\(manual save\)|good morning|good evening|good afternoon|cannot reach|could not|unable to|warning:|error:|loaded tui session|session restored|restored previous)/i.test(core);
607581
+ return /^(nexus|rest api|voice feedback|clone ref|connecting to|connected|http:\/\/|https:\/\/|last task:|\(manual save\)|good morning|good evening|good afternoon|cannot reach|could not|unable to|warning:|error:|loaded tui session|session restored|restored previous|using (expanded )?context model|using model|tui session\b|chat tui:|previous session found|context (auto-)?restored|context restored|recovered session|\[vram|vram |model_info|kv |arch[ -]capped)/i.test(core);
607582
607582
  }
607583
607583
  function firstMeaningfulLine(transcript) {
607584
- for (const raw of transcript.split("\n")) {
607585
- const line = raw.replace(ANSI_RE, "").trim();
607586
- if (line && !isNoiseLine(line)) return line;
607584
+ const lines = transcript.split("\n").map((r2) => r2.replace(ANSI_RE, "").trim());
607585
+ for (const line of lines) {
607586
+ if (/^[▹▸►❯>]\s+\S/.test(line) && !isNoiseLine(line)) return line;
607587
607587
  }
607588
- for (const raw of transcript.split("\n")) {
607589
- const line = raw.replace(ANSI_RE, "").trim();
607590
- if (line) return line;
607588
+ for (const line of lines) {
607589
+ if (line && !isNoiseLine(line)) return line;
607591
607590
  }
607592
607591
  return "";
607593
607592
  }
@@ -607598,8 +607597,9 @@ function clamp7(value2, max) {
607598
607597
  function deterministicSummary(transcript) {
607599
607598
  const first2 = firstMeaningfulLine(transcript);
607600
607599
  if (!first2) return { title: "Untitled session", summary: "Empty session." };
607601
- const title = clamp7(first2.replace(/^[>›$#\s]+/, ""), TITLE_MAX);
607602
- return { title: title || "Untitled session", summary: clamp7(first2, SUMMARY_MAX) };
607600
+ const cleaned = first2.replace(TUI_MARKER_PREFIX, "").replace(/^[>›$#\s]+/, "").trim();
607601
+ const title = clamp7(cleaned, TITLE_MAX);
607602
+ return { title: title || "Untitled session", summary: clamp7(cleaned || first2, SUMMARY_MAX) };
607603
607603
  }
607604
607604
  function parseSummaryReply(content) {
607605
607605
  if (!content) return null;
@@ -607692,7 +607692,7 @@ function sessionDisplayTitle(entry) {
607692
607692
  if (entry.aiTitle && entry.aiTitle.trim()) return entry.aiTitle.trim();
607693
607693
  return deterministicSummary(entry.name || "").title;
607694
607694
  }
607695
- var TITLE_MAX, SUMMARY_MAX, TRANSCRIPT_CHARS, ANSI_RE, _inflightSummaries;
607695
+ var TITLE_MAX, SUMMARY_MAX, TRANSCRIPT_CHARS, ANSI_RE, TUI_MARKER_PREFIX, _inflightSummaries;
607696
607696
  var init_session_summary = __esm({
607697
607697
  "packages/cli/src/api/session-summary.ts"() {
607698
607698
  "use strict";
@@ -607702,6 +607702,7 @@ var init_session_summary = __esm({
607702
607702
  SUMMARY_MAX = 160;
607703
607703
  TRANSCRIPT_CHARS = 6e3;
607704
607704
  ANSI_RE = /\x1B\[[0-9;]*m|\x1B\][^\x07]*(?:\x07|\x1B\\)/g;
607705
+ TUI_MARKER_PREFIX = /^[∙•·‹›▹▸▶►◆◇❯❮>\-=_*#|/\\.\s]+/;
607705
607706
  _inflightSummaries = /* @__PURE__ */ new Set();
607706
607707
  }
607707
607708
  });
@@ -696759,6 +696760,7 @@ function getOpenApiSpec() {
696759
696760
  },
696760
696761
  "/v1/chat/sessions": { get: { summary: "List active chat sessions", tags: ["Chat"], responses: { 200: { description: "Session list" } } } },
696761
696762
  "/v1/chat/sessions/{id}/summarize": { post: { summary: "Generate + cache an inference-based title/summary for a session — body {force?, root?}", tags: ["Chat"], responses: { 200: { description: "Title + summary" }, 500: { description: "Generation failed" } } } },
696763
+ "/v1/chat/sessions/{id}/status": { get: { summary: "Reactive recall: is this session running right now + unseen deltas since ?since=<seq> (running, phase, seq, partial, deltas[])", tags: ["Chat"], responses: { 200: { description: "Live run status + catch-up deltas" } } } },
696762
696764
  // ───── AIWG cascade ─────
696763
696765
  "/v1/aiwg": { get: { summary: "AIWG installation root + control map", tags: ["AIWG"], responses: { 200: { description: "AIWG installation summary" } } } },
696764
696766
  "/v1/aiwg/frameworks": { get: { summary: "List AIWG frameworks (paginated)", tags: ["AIWG"], responses: { 200: { description: "Framework list" } } } },
@@ -697523,6 +697525,96 @@ var init_usage_tracker = __esm({
697523
697525
  }
697524
697526
  });
697525
697527
 
697528
+ // packages/cli/src/api/chat-run-registry.ts
697529
+ function getChatRunRegistry() {
697530
+ if (!_registry5) _registry5 = new ChatRunRegistry();
697531
+ return _registry5;
697532
+ }
697533
+ var MAX_BUFFER2, ChatRunRegistry, _registry5;
697534
+ var init_chat_run_registry = __esm({
697535
+ "packages/cli/src/api/chat-run-registry.ts"() {
697536
+ "use strict";
697537
+ MAX_BUFFER2 = 400;
697538
+ ChatRunRegistry = class {
697539
+ runs = /* @__PURE__ */ new Map();
697540
+ /** Begin (or restart) a run for a session. Returns the fresh state. */
697541
+ start(sessionId, label) {
697542
+ const now2 = Date.now();
697543
+ const state = {
697544
+ sessionId,
697545
+ phase: "running",
697546
+ startedAt: now2,
697547
+ lastActivityMs: now2,
697548
+ seq: 0,
697549
+ buffer: [],
697550
+ partial: "",
697551
+ ...label ? { label } : {}
697552
+ };
697553
+ this.runs.set(sessionId, state);
697554
+ return state;
697555
+ }
697556
+ /** Append a live delta to a running session; no-op if unknown. Returns the seq. */
697557
+ push(sessionId, delta) {
697558
+ const state = this.runs.get(sessionId);
697559
+ if (!state) return -1;
697560
+ const seq = ++state.seq;
697561
+ const entry = { seq, ts: Date.now(), ...delta };
697562
+ state.buffer.push(entry);
697563
+ if (state.buffer.length > MAX_BUFFER2) state.buffer.splice(0, state.buffer.length - MAX_BUFFER2);
697564
+ if (delta.kind === "assistant_delta" && delta.text) state.partial += delta.text;
697565
+ state.lastActivityMs = entry.ts;
697566
+ return seq;
697567
+ }
697568
+ /** Mark a run finished. Keeps the state briefly so late visitors see the result. */
697569
+ finish(sessionId, phase = "completed") {
697570
+ const state = this.runs.get(sessionId);
697571
+ if (!state) return;
697572
+ state.phase = phase;
697573
+ state.lastActivityMs = Date.now();
697574
+ this.push(sessionId, { kind: phase === "completed" ? "done" : "error" });
697575
+ }
697576
+ /** Current status for a session (null when never run this daemon lifetime). */
697577
+ status(sessionId) {
697578
+ const s2 = this.runs.get(sessionId);
697579
+ if (!s2) return null;
697580
+ return {
697581
+ running: s2.phase === "running",
697582
+ phase: s2.phase,
697583
+ lastActivityMs: s2.lastActivityMs,
697584
+ seq: s2.seq,
697585
+ ...s2.label ? { label: s2.label } : {}
697586
+ };
697587
+ }
697588
+ /** Deltas the client hasn't seen yet (seq > sinceSeq), for live catch-up. */
697589
+ since(sessionId, sinceSeq) {
697590
+ const s2 = this.runs.get(sessionId);
697591
+ if (!s2) return null;
697592
+ return { deltas: s2.buffer.filter((d2) => d2.seq > sinceSeq), partial: s2.partial, phase: s2.phase };
697593
+ }
697594
+ /** True while a session is actively producing output. */
697595
+ isRunning(sessionId) {
697596
+ return this.runs.get(sessionId)?.phase === "running";
697597
+ }
697598
+ /** Drop a session's run state (e.g. on delete). */
697599
+ clear(sessionId) {
697600
+ this.runs.delete(sessionId);
697601
+ }
697602
+ /** Evict finished runs older than `maxAgeMs` to bound memory. */
697603
+ sweep(maxAgeMs = 30 * 60 * 1e3, now2 = Date.now()) {
697604
+ let removed = 0;
697605
+ for (const [id, s2] of this.runs) {
697606
+ if (s2.phase !== "running" && now2 - s2.lastActivityMs > maxAgeMs) {
697607
+ this.runs.delete(id);
697608
+ removed++;
697609
+ }
697610
+ }
697611
+ return removed;
697612
+ }
697613
+ };
697614
+ _registry5 = null;
697615
+ }
697616
+ });
697617
+
697526
697618
  // packages/cli/src/docker.ts
697527
697619
  import { execSync as execSync59, spawn as spawn32 } from "node:child_process";
697528
697620
  import { existsSync as existsSync156, mkdirSync as mkdirSync98, writeFileSync as writeFileSync83 } from "node:fs";
@@ -705017,6 +705109,13 @@ data: ${JSON.stringify(data)}
705017
705109
  const realtimeOpts = realtimeEnabled ? realtimeOptionsFromBody(chatBody, cwdPath, session.id) : null;
705018
705110
  addUserMessage(session, chatBody.message);
705019
705111
  compactSession(session);
705112
+ {
705113
+ const _runReg = getChatRunRegistry();
705114
+ _runReg.start(session.id, String(chatBody.message).slice(0, 80));
705115
+ res.on("close", () => {
705116
+ _runReg.finish(session.id, res.writableEnded ? "completed" : "aborted");
705117
+ });
705118
+ }
705020
705119
  const streamMode = chatBody.stream !== false;
705021
705120
  const toolsField = chatBody["tools"];
705022
705121
  const isOpenAIToolsArray = Array.isArray(toolsField) && toolsField.length > 0 && toolsField.every(
@@ -705735,6 +705834,29 @@ ${historyLines}
705735
705834
  });
705736
705835
  return;
705737
705836
  }
705837
+ const chatStatusMatch = pathname.match(/^\/v1\/chat\/sessions\/([^/]+)\/status$/);
705838
+ if (chatStatusMatch && method === "GET") {
705839
+ if (!checkAuth(req3, res, "read")) return;
705840
+ const sid = decodeURIComponent(chatStatusMatch[1]);
705841
+ const reg = getChatRunRegistry();
705842
+ const st = reg.status(sid);
705843
+ if (!st) {
705844
+ jsonResponse(res, 200, { session_id: sid, running: false, phase: "idle", seq: 0 });
705845
+ return;
705846
+ }
705847
+ const sinceSeq = Number(new URL(req3.url || "", "http://localhost").searchParams.get("since") ?? "0") || 0;
705848
+ const catchUp = reg.since(sid, sinceSeq);
705849
+ jsonResponse(res, 200, {
705850
+ session_id: sid,
705851
+ running: st.running,
705852
+ phase: st.phase,
705853
+ seq: st.seq,
705854
+ lastActivityMs: st.lastActivityMs,
705855
+ ...st.label ? { label: st.label } : {},
705856
+ ...catchUp ? { deltas: catchUp.deltas, partial: catchUp.partial } : {}
705857
+ });
705858
+ return;
705859
+ }
705738
705860
  const chatSessionMatch = pathname.match(/^\/v1\/chat\/sessions\/([^/]+)$/);
705739
705861
  if (chatSessionMatch) {
705740
705862
  const sid = decodeURIComponent(chatSessionMatch[1]);
@@ -708388,6 +708510,7 @@ var init_serve = __esm({
708388
708510
  init_usage_tracker();
708389
708511
  init_omnius_directory();
708390
708512
  init_session_summary();
708513
+ init_chat_run_registry();
708391
708514
  init_omnius_directory();
708392
708515
  init_command_registry();
708393
708516
  init_profiles();
@@ -52,6 +52,7 @@ pnpm docs:check
52
52
  | `GET` | `/api/tags` | Ollama-compatible model tags |
53
53
  | `GET` | `/v1/chat/sessions` | Active chat sessions |
54
54
  | `POST` | `/v1/chat/sessions/{id}/summarize` | Generate + cache an inference-based session title/summary |
55
+ | `GET` | `/v1/chat/sessions/{id}/status` | Reactive recall: live run status + unseen deltas (`?since=<seq>`) |
55
56
  | `POST` | `/v1/chat/check-in` | Steering check-in for active chat |
56
57
 
57
58
  ## Agentic Runs
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.335",
3
+ "version": "1.0.336",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.335",
9
+ "version": "1.0.336",
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.335",
3
+ "version": "1.0.336",
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",