@inerrata-corporation/errata 2.0.2-dev.615 → 2.0.2-dev.627

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.
Files changed (2) hide show
  1. package/errata.mjs +56 -10
  2. package/package.json +1 -1
package/errata.mjs CHANGED
@@ -48115,6 +48115,48 @@ var init_outbox = __esm({
48115
48115
  }
48116
48116
  });
48117
48117
 
48118
+ // src/message-accumulator.ts
48119
+ function createMessageAccumulator(opts = {}) {
48120
+ const ttlMs = opts.ttlMs ?? MESSAGE_BUFFER_TTL_MS;
48121
+ const buffers = /* @__PURE__ */ new Map();
48122
+ const evictStale = (nowMs) => {
48123
+ for (const [id, b] of buffers) {
48124
+ if (nowMs - b.lastAt > ttlMs) buffers.delete(id);
48125
+ }
48126
+ };
48127
+ return {
48128
+ accumulate(messageId, index, delta, isFinal, nowMs) {
48129
+ if (!messageId) return isFinal ? { text: delta } : null;
48130
+ evictStale(nowMs);
48131
+ let b = buffers.get(messageId);
48132
+ if (!b) {
48133
+ b = { chunks: /* @__PURE__ */ new Map(), lastAt: nowMs };
48134
+ buffers.set(messageId, b);
48135
+ }
48136
+ b.chunks.set(index, delta);
48137
+ if (isFinal) b.finalIndex = index;
48138
+ b.lastAt = nowMs;
48139
+ if (b.finalIndex === void 0) return null;
48140
+ for (let i2 = 0; i2 <= b.finalIndex; i2++) {
48141
+ if (!b.chunks.has(i2)) return null;
48142
+ }
48143
+ const text = [...b.chunks.entries()].sort((a, z2) => a[0] - z2[0]).map(([, d]) => d).join("");
48144
+ buffers.delete(messageId);
48145
+ return { text };
48146
+ },
48147
+ size() {
48148
+ return buffers.size;
48149
+ }
48150
+ };
48151
+ }
48152
+ var MESSAGE_BUFFER_TTL_MS;
48153
+ var init_message_accumulator = __esm({
48154
+ "src/message-accumulator.ts"() {
48155
+ "use strict";
48156
+ MESSAGE_BUFFER_TTL_MS = 5 * 60 * 1e3;
48157
+ }
48158
+ });
48159
+
48118
48160
  // src/webui.ts
48119
48161
  var webui_exports = {};
48120
48162
  __export(webui_exports, {
@@ -48125,6 +48167,9 @@ __export(webui_exports, {
48125
48167
  recallForFile: () => recallForFile,
48126
48168
  recallForTool: () => recallForTool
48127
48169
  });
48170
+ function accumulateMessageDelta(messageId, index, delta, isFinal, nowMs) {
48171
+ return messageAccumulator.accumulate(messageId, index, delta, isFinal, nowMs);
48172
+ }
48128
48173
  function fileUriToFsPath(raw2) {
48129
48174
  let p = raw2.replace(/^file:\/\//, "").replace(/\\/g, "/");
48130
48175
  if (/^\/[A-Za-z]:/.test(p)) p = p.slice(1);
@@ -48512,17 +48557,16 @@ function buildWebUi(deps) {
48512
48557
  } catch {
48513
48558
  return c.json({ error: "bad-json" }, 400);
48514
48559
  }
48515
- const text = String(body2["delta"] ?? "");
48560
+ const delta = String(body2["delta"] ?? "");
48516
48561
  const sessionId = String(body2["session_id"] ?? "");
48517
48562
  const messageId = typeof body2["message_id"] === "string" ? body2["message_id"] : void 0;
48518
- if (body2["final"] === false) return c.json({ ok: true, skipped: "partial" });
48519
- if (typeof body2["index"] === "number" && body2["index"] > 0) {
48520
- console.warn(`[errata] MessageDisplay arrived chunked (index ${body2["index"]}) \u2014 delta accumulation needed, text may be partial`);
48521
- }
48522
- if (text && sessionId && deps.onMessage) {
48523
- deps.onMessage({ sessionId, text, ...messageId ? { messageId } : {} });
48563
+ const index = typeof body2["index"] === "number" ? body2["index"] : 0;
48564
+ const isFinal = body2["final"] !== false;
48565
+ const whole = accumulateMessageDelta(messageId, index, delta, isFinal, Date.now());
48566
+ if (whole !== null && whole.text && sessionId && deps.onMessage) {
48567
+ deps.onMessage({ sessionId, text: whole.text, ...messageId ? { messageId } : {} });
48524
48568
  }
48525
- return c.json({ ok: true });
48569
+ return c.json({ ok: true, ...whole === null ? { buffered: true } : {} });
48526
48570
  });
48527
48571
  app.post("/api/session-end", async (c) => {
48528
48572
  let body2;
@@ -48735,7 +48779,7 @@ function proposalToIngest(p, profile, daemonVersion) {
48735
48779
  payloadDigest: p.id
48736
48780
  };
48737
48781
  }
48738
- var wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, META_LABELS;
48782
+ var messageAccumulator, wsPackagesCache, WS_PACKAGES_TTL_MS, loggedToolSessions, META_LABELS;
48739
48783
  var init_webui = __esm({
48740
48784
  "src/webui.ts"() {
48741
48785
  "use strict";
@@ -48747,6 +48791,8 @@ var init_webui = __esm({
48747
48791
  init_vfile();
48748
48792
  init_tool_index();
48749
48793
  init_outbox();
48794
+ init_message_accumulator();
48795
+ messageAccumulator = createMessageAccumulator();
48750
48796
  wsPackagesCache = /* @__PURE__ */ new WeakMap();
48751
48797
  WS_PACKAGES_TTL_MS = 6e4;
48752
48798
  loggedToolSessions = /* @__PURE__ */ new Set();
@@ -54754,7 +54800,7 @@ function startLoopLagMonitor(thresholdMs = 1e3) {
54754
54800
  }
54755
54801
 
54756
54802
  // src/engine.ts
54757
- var DAEMON_VERSION = true ? "2.0.2-dev.615" : "2.0.0-alpha.0";
54803
+ var DAEMON_VERSION = true ? "2.0.2-dev.627" : "2.0.0-alpha.0";
54758
54804
  var IGNORED_PATH = /[\\/](?:\.git|node_modules|\.errata|\.claude|\.codex|\.cursor|\.turbo|\.next|dist|coverage|test-results|playwright-report|__pycache__)(?:[\\/]|$)/;
54759
54805
  var IGNORED_NOISE = /castalia\.db|eventlog\.sqlite|turn-cursors/;
54760
54806
  var GIT_OP_MUTE_MS = 4e3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inerrata-corporation/errata",
3
- "version": "2.0.2-dev.615",
3
+ "version": "2.0.2-dev.627",
4
4
  "description": "errata - local-first observation engine for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {