@ai-matrx/content-ir 0.18.5 → 0.19.0

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/source.cjs CHANGED
@@ -270,12 +270,6 @@ function fenceOpenerOf(content) {
270
270
  return null;
271
271
  }
272
272
  var FenceReader = class {
273
- constructor(opener, options = {}) {
274
- this.opener = opener;
275
- this.isJson = opener.char === "`" && opener.lang === "json";
276
- this.nesting = opener.char === "`" && (options.nesting ?? fenceNestsInnerFences(opener.lang));
277
- this.tildeCloser = opener.char === "~" ? new RegExp(`^ {0,3}~{${opener.ticks},}[ \\t]*$`) : null;
278
- }
279
273
  opener;
280
274
  state = { inString: false, escaped: false };
281
275
  depth = 0;
@@ -284,6 +278,12 @@ var FenceReader = class {
284
278
  isJson;
285
279
  nesting;
286
280
  tildeCloser;
281
+ constructor(opener, options = {}) {
282
+ this.opener = opener;
283
+ this.isJson = opener.char === "`" && opener.lang === "json";
284
+ this.nesting = opener.char === "`" && (options.nesting ?? fenceNestsInnerFences(opener.lang));
285
+ this.tildeCloser = opener.char === "~" ? new RegExp(`^ {0,3}~{${opener.ticks},}[ \\t]*$`) : null;
286
+ }
287
287
  /** How many nested fences are open right now. */
288
288
  get nestedDepth() {
289
289
  return this.depth;
@@ -901,9 +901,6 @@ function isEscapedBacktick(line, offset) {
901
901
  return slashes % 2 === 1;
902
902
  }
903
903
  var XmlContainerTracker = class {
904
- constructor(rootTag) {
905
- this.rootTag = rootTag;
906
- }
907
904
  rootTag;
908
905
  depth = 0;
909
906
  inComment = false;
@@ -911,6 +908,9 @@ var XmlContainerTracker = class {
911
908
  inlineTicks = 0;
912
909
  /** The open fence, read by THE one closer (source/code-ranges.ts). */
913
910
  fence = null;
911
+ constructor(rootTag) {
912
+ this.rootTag = rootTag;
913
+ }
914
914
  consumeLine(line, startOffset = 0) {
915
915
  if (this.fence) {
916
916
  if (this.fence.feed(line)) this.fence = null;
@@ -1122,6 +1122,23 @@ function isSplitterTreeLine(line) {
1122
1122
  }
1123
1123
  var MEDIA_REF_PREFIXES = ["[Image URL:", "[Video URL:", "[Audio URL:"];
1124
1124
  var Tokenizer = class {
1125
+ text;
1126
+ streaming;
1127
+ meter;
1128
+ n;
1129
+ lineStarts = [];
1130
+ contentEnds = [];
1131
+ lineEnds = [];
1132
+ blocks = [];
1133
+ blockCache = /* @__PURE__ */ new Map();
1134
+ /** Lazily built: for line i, first line j >= i where brace net from i drops to <= 0. */
1135
+ braceStop = null;
1136
+ braceNet = null;
1137
+ /** Every occurrence offset of each needle searched so far (overlapping, like indexOf). */
1138
+ occurrences = /* @__PURE__ */ new Map();
1139
+ /** `$$` opener → closer for the pairs the core renders as math. */
1140
+ mathPairs;
1141
+ finder = (needle, from) => this.next(needle, from);
1125
1142
  constructor(text, streaming = false, meter = void 0) {
1126
1143
  this.text = text;
1127
1144
  this.streaming = streaming;
@@ -1168,23 +1185,6 @@ var Tokenizer = class {
1168
1185
  this.lineEnds.push(text.length);
1169
1186
  }
1170
1187
  }
1171
- text;
1172
- streaming;
1173
- meter;
1174
- n;
1175
- lineStarts = [];
1176
- contentEnds = [];
1177
- lineEnds = [];
1178
- blocks = [];
1179
- blockCache = /* @__PURE__ */ new Map();
1180
- /** Lazily built: for line i, first line j >= i where brace net from i drops to <= 0. */
1181
- braceStop = null;
1182
- braceNet = null;
1183
- /** Every occurrence offset of each needle searched so far (overlapping, like indexOf). */
1184
- occurrences = /* @__PURE__ */ new Map();
1185
- /** `$$` opener → closer for the pairs the core renders as math. */
1186
- mathPairs;
1187
- finder = (needle, from) => this.next(needle, from);
1188
1188
  /** Streaming: where provisional text starts (a pending `$$`), or +∞. */
1189
1189
  provisionalFrom = Number.POSITIVE_INFINITY;
1190
1190
  /** Streaming: the text ends in a lone CR whose LF has not arrived yet. */
@@ -1241,10 +1241,13 @@ var Tokenizer = class {
1241
1241
  /**
1242
1242
  * Streaming: an open block that may still turn back into prose — a `$$`
1243
1243
  * pair whose closer is on the open last line (prose after it makes it
1244
- * inline), or a JSON head whose braces have not balanced (it may never parse).
1244
+ * inline), a JSON head whose braces have not balanced (it may never parse),
1245
+ * or any opener that is itself still arriving on the open last line.
1245
1246
  */
1246
1247
  mayDissolve(block) {
1247
- return this.streaming && !block.complete && (block.type === "math_block" || block.type === "json");
1248
+ if (!this.streaming || block.complete) return false;
1249
+ if (block.type === "math_block" || block.type === "json") return true;
1250
+ return this.isOpenTail(this.lineOf(block.start));
1248
1251
  }
1249
1252
  /** Streaming: paragraph ends where an undecided, dissolvable block cut them short. */
1250
1253
  undecidedBreaks = /* @__PURE__ */ new Set();
@@ -1265,6 +1268,12 @@ var Tokenizer = class {
1265
1268
  }
1266
1269
  return lo;
1267
1270
  }
1271
+ /** How many whitespace characters open the text at `from` (up to `to`). */
1272
+ leadingSpace(from, to) {
1273
+ let k = from;
1274
+ while (k < to && /\s/.test(this.text[k])) k++;
1275
+ return k - from;
1276
+ }
1268
1277
  isBlank(from, to) {
1269
1278
  return !NOT_WHITESPACE.test(this.text.slice(from, to));
1270
1279
  }
@@ -1289,6 +1298,10 @@ var Tokenizer = class {
1289
1298
  break;
1290
1299
  }
1291
1300
  const island = this.detectBlock(pos, li, true);
1301
+ if (island && pos + this.leadingSpace(pos, this.contentEnds[li]) >= this.provisionalFrom) {
1302
+ this.push({ kind: "prose", start: pos, end: this.n, island: null, inlines: [] });
1303
+ break;
1304
+ }
1292
1305
  if (island) {
1293
1306
  this.push({ kind: "island", start: island.start, end: island.end, island, inlines: [] });
1294
1307
  pos = island.end;
@@ -1318,12 +1331,6 @@ var Tokenizer = class {
1318
1331
  const last = this.lineStarts.length - 1;
1319
1332
  if (last < 0) return;
1320
1333
  if (this.isOpenTail(last)) {
1321
- const lineStart = this.lineStarts[last];
1322
- for (const block2 of this.blocks) {
1323
- if (block2.kind === "prose" && block2.end > lineStart) {
1324
- block2.inlines = block2.inlines.filter((inline) => inline.end <= lineStart);
1325
- }
1326
- }
1327
1334
  let b = this.blocks.length - 1;
1328
1335
  while (b >= 0 && this.blocks[b].kind === "gap") b--;
1329
1336
  const block = this.blocks[b];
@@ -1349,36 +1356,55 @@ var Tokenizer = class {
1349
1356
  * region…) is never a tree line nor a root label, so it stops the walk.
1350
1357
  */
1351
1358
  treeRootHoldFrom() {
1352
- const claimable = (k2) => {
1359
+ const claimFrom = (k2) => {
1360
+ const lineStart = this.lineStarts[k2];
1361
+ const lineEnd = this.contentEnds[k2];
1362
+ let pos = lineStart;
1353
1363
  for (; ; ) {
1354
- const block = this.blockAt(this.lineStarts[k2]);
1355
- if (!block || block.kind !== "island" || block.island?.fromParagraph === true) return true;
1356
- const opened = this.lineOf(block.start);
1357
- if (this.lineStarts[opened] === block.start || opened === k2) return false;
1358
- k2 = opened;
1364
+ const block = this.blockAt(pos);
1365
+ if (!block || block.kind !== "island" || !block.island) return pos;
1366
+ if (block.island.fromParagraph === true || this.mayDissolve(block.island)) return pos;
1367
+ if (block.start < lineStart) {
1368
+ const opened = this.lineOf(block.start);
1369
+ if (this.lineStarts[opened] !== block.start && claimFrom(opened) !== -1) return pos;
1370
+ if (block.end >= lineEnd) return -1;
1371
+ pos = block.end;
1372
+ continue;
1373
+ }
1374
+ if (block.end >= lineEnd) return -1;
1375
+ pos = block.end;
1359
1376
  }
1360
1377
  };
1361
1378
  let k = this.lineCount - 1;
1362
1379
  let start = this.lineCount;
1380
+ let startPos = this.n;
1363
1381
  if (k >= 0 && this.isOpenTail(k)) {
1364
- if (!claimable(k)) return this.n;
1382
+ const at = claimFrom(k);
1383
+ if (at === -1) return this.n;
1365
1384
  start = k;
1385
+ startPos = at;
1366
1386
  k--;
1367
1387
  }
1368
- for (; k >= 0 && claimable(k); k--) {
1388
+ for (; k >= 0; k--) {
1369
1389
  this.tick(1);
1390
+ const at = claimFrom(k);
1391
+ if (at === -1) break;
1370
1392
  if (this.lineIsBlank(k)) continue;
1371
1393
  if (!TREE_GLYPHS.test(this.lineText(k))) break;
1372
1394
  start = k;
1395
+ startPos = at;
1373
1396
  }
1374
- let root = start;
1375
- for (let j = start - 1; j >= 0 && claimable(j); j--) {
1397
+ let rootPos = startPos;
1398
+ for (let j = start - 1; j >= 0; j--) {
1399
+ const at = claimFrom(j);
1400
+ if (at === -1) break;
1376
1401
  const trimmed = this.lineText(j).trim();
1377
1402
  this.tick(trimmed.length + 1);
1378
1403
  if (!trimmed || isSplitterTreeLine(trimmed) || /^#{1,6}\s/.test(trimmed)) break;
1379
- root = j;
1404
+ rootPos = at;
1405
+ if (at > this.lineStarts[j]) break;
1380
1406
  }
1381
- return root < this.lineCount ? this.lineStarts[root] : this.n;
1407
+ return rootPos;
1382
1408
  }
1383
1409
  /** The block (so far) containing offset `pos`, or null. */
1384
1410
  blockAt(pos) {
@@ -1910,7 +1936,9 @@ var Tokenizer = class {
1910
1936
  const block = this.detectBlock(this.lineStarts[k], k, false);
1911
1937
  if (block) {
1912
1938
  breakLine = k;
1913
- if (this.mayDissolve(block)) this.undecidedBreaks.add(end);
1939
+ if (this.mayDissolve(block) || this.streaming && block.start >= this.provisionalFrom) {
1940
+ this.undecidedBreaks.add(end);
1941
+ }
1914
1942
  break;
1915
1943
  }
1916
1944
  end = this.contentEnds[k];
@@ -2148,6 +2176,10 @@ var Tokenizer = class {
2148
2176
  const closer = `</${name}>`;
2149
2177
  const close = this.next(closer, tagEnd);
2150
2178
  const blockType = isAttr ? "xml_attr" : "xml_region";
2179
+ if (close === -1 && isThinking && !this.streaming) {
2180
+ i = tagEnd;
2181
+ continue;
2182
+ }
2151
2183
  if (close === -1) return stop(this.island(blockType, i, this.n, false, { tag: name }));
2152
2184
  const end = close + closer.length;
2153
2185
  if (end > pe) return stop(this.spill(blockType, i, end, pe, { tag: name }));
@@ -2251,12 +2283,12 @@ function blockAt(blocks, offset) {
2251
2283
 
2252
2284
  // source/splice.ts
2253
2285
  var SourceSpliceError = class extends Error {
2286
+ code;
2254
2287
  constructor(code, message) {
2255
2288
  super(message);
2256
2289
  this.code = code;
2257
2290
  this.name = "SourceSpliceError";
2258
2291
  }
2259
- code;
2260
2292
  };
2261
2293
  function blockEdit(block, text) {
2262
2294
  return { start: block.start, end: block.end, text };