@ai-matrx/content-ir 0.22.6 → 0.23.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/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var textCase = require('@ai-matrx/kit/text-case');
3
4
  var Ajv = require('ajv');
4
5
 
5
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -2127,313 +2128,8 @@ function stripKindDeep(value) {
2127
2128
  }
2128
2129
  return value;
2129
2130
  }
2130
-
2131
- // text-case.ts
2132
- var DEFAULT_WORD_REPLACEMENTS = {
2133
- // Acronyms & initialisms
2134
- "api": "API",
2135
- "apis": "APIs",
2136
- "ui": "UI",
2137
- "ux": "UX",
2138
- "id": "ID",
2139
- "ids": "IDs",
2140
- "qr": "QR",
2141
- "ssr": "SSR",
2142
- "csr": "CSR",
2143
- "ssg": "SSG",
2144
- "isr": "ISR",
2145
- "spa": "SPA",
2146
- "pwa": "PWA",
2147
- "sdk": "SDK",
2148
- "sdks": "SDKs",
2149
- "cli": "CLI",
2150
- "tty": "TTY",
2151
- "repl": "REPL",
2152
- "ci": "CI",
2153
- "cd": "CD",
2154
- "cpu": "CPU",
2155
- "cpus": "CPUs",
2156
- "gpu": "GPU",
2157
- "gpus": "GPUs",
2158
- "ram": "RAM",
2159
- "rom": "ROM",
2160
- "ssd": "SSD",
2161
- "ssds": "SSDs",
2162
- "hdd": "HDD",
2163
- "hdds": "HDDs",
2164
- "kpi": "KPI",
2165
- "kpis": "KPIs",
2166
- "sla": "SLA",
2167
- "slas": "SLAs",
2168
- "slo": "SLO",
2169
- "slos": "SLOs",
2170
- "sli": "SLI",
2171
- "slis": "SLIs",
2172
- "dom": "DOM",
2173
- // Web, formats, protocols
2174
- "url": "URL",
2175
- "urls": "URLs",
2176
- "uri": "URI",
2177
- "uris": "URIs",
2178
- "http": "HTTP",
2179
- "https": "HTTPS",
2180
- "html": "HTML",
2181
- "css": "CSS",
2182
- "json": "JSON",
2183
- "yaml": "YAML",
2184
- "yml": "YML",
2185
- "toml": "TOML",
2186
- "csv": "CSV",
2187
- "pdf": "PDF",
2188
- "tsv": "TSV",
2189
- "jpg": "JPG",
2190
- "jpeg": "JPEG",
2191
- "png": "PNG",
2192
- "gif": "GIF",
2193
- "webp": "WebP",
2194
- "heic": "HEIC",
2195
- "heif": "HEIF",
2196
- "bmp": "BMP",
2197
- "tiff": "TIFF",
2198
- "ico": "ICO",
2199
- "xml": "XML",
2200
- "sql": "SQL",
2201
- "db": "DB",
2202
- "dbs": "DBs",
2203
- "nosql": "NoSQL",
2204
- "graphql": "GraphQL",
2205
- "grpc": "gRPC",
2206
- "rest": "REST",
2207
- "restful": "RESTful",
2208
- "websocket": "WebSocket",
2209
- "websockets": "WebSockets",
2210
- "webrtc": "WebRTC",
2211
- // Networking
2212
- "ip": "IP",
2213
- "ipv4": "IPv4",
2214
- "ipv6": "IPv6",
2215
- "dns": "DNS",
2216
- "dhcp": "DHCP",
2217
- "nat": "NAT",
2218
- "tcp": "TCP",
2219
- "udp": "UDP",
2220
- "icmp": "ICMP",
2221
- "ttl": "TTL",
2222
- "lan": "LAN",
2223
- "wan": "WAN",
2224
- "vlan": "VLAN",
2225
- "cdn": "CDN",
2226
- "ftp": "FTP",
2227
- "ssh": "SSH",
2228
- "tls": "TLS",
2229
- "ssl": "SSL",
2230
- // Security & crypto
2231
- "jwt": "JWT",
2232
- "jws": "JWS",
2233
- "jwe": "JWE",
2234
- "hmac": "HMAC",
2235
- "rsa": "RSA",
2236
- "ecdsa": "ECDSA",
2237
- "aes": "AES",
2238
- "pbkdf2": "PBKDF2",
2239
- "argon2": "Argon2",
2240
- "scrypt": "scrypt",
2241
- "totp": "TOTP",
2242
- "hotp": "HOTP",
2243
- "mfa": "MFA",
2244
- "2fa": "2FA",
2245
- "csrf": "CSRF",
2246
- "xss": "XSS",
2247
- "ssrf": "SSRF",
2248
- "rce": "RCE",
2249
- "dos": "DoS",
2250
- "ddos": "DDoS",
2251
- "mitm": "MITM",
2252
- "csp": "CSP",
2253
- "cors": "CORS",
2254
- "pii": "PII",
2255
- "phi": "PHI",
2256
- "gdpr": "GDPR",
2257
- "ccpa": "CCPA",
2258
- "hipaa": "HIPAA",
2259
- "rfc": "RFC",
2260
- // Platforms, langs, tools (single-token)
2261
- "javascript": "JavaScript",
2262
- "typescript": "TypeScript",
2263
- "jsx": "JSX",
2264
- "tsx": "TSX",
2265
- "node": "Node",
2266
- // (used when tokenized alone)
2267
- "deno": "Deno",
2268
- "bun": "Bun",
2269
- "react": "React",
2270
- "nextjs": "Next.js",
2271
- // if your tokenizer drops dots, keep this
2272
- "nodejs": "Node.js",
2273
- "postgresql": "PostgreSQL",
2274
- "postgres": "Postgres",
2275
- "mysql": "MySQL",
2276
- "sqlite": "SQLite",
2277
- "redis": "Redis",
2278
- "supabase": "Supabase",
2279
- "docker": "Docker",
2280
- "kubernetes": "Kubernetes",
2281
- "k8s": "Kubernetes",
2282
- "helm": "Helm",
2283
- "npm": "npm",
2284
- "pnpm": "pnpm",
2285
- "yarn": "Yarn",
2286
- "eslint": "ESLint",
2287
- "prettier": "Prettier",
2288
- "vite": "Vite",
2289
- "webpack": "Webpack",
2290
- "babel": "Babel",
2291
- // OS & vendors
2292
- "macos": "macOS",
2293
- "ios": "iOS",
2294
- "ipados": "iPadOS",
2295
- "watchos": "watchOS",
2296
- "tvos": "tvOS",
2297
- "windows": "Windows",
2298
- "linux": "Linux",
2299
- "ubuntu": "Ubuntu",
2300
- "github": "GitHub",
2301
- "gitlab": "GitLab",
2302
- "bitbucket": "Bitbucket",
2303
- // Data & analytics
2304
- "etl": "ETL",
2305
- "elt": "ELT",
2306
- "olap": "OLAP",
2307
- "oltp": "OLTP",
2308
- "bi": "BI",
2309
- // Time & locales
2310
- "utc": "UTC",
2311
- "gmt": "GMT",
2312
- "pst": "PST",
2313
- "pdt": "PDT",
2314
- "pt": "PT",
2315
- // Common “small words” to keep lowercase (unless first/last word)
2316
- "or": "or",
2317
- "and": "and",
2318
- "the": "the",
2319
- "of": "of",
2320
- "in": "in",
2321
- "to": "to",
2322
- "with": "with",
2323
- "as": "as",
2324
- "by": "by",
2325
- "for": "for",
2326
- "on": "on",
2327
- "at": "at",
2328
- "up": "up",
2329
- "a": "a",
2330
- "an": "an",
2331
- "is": "is",
2332
- "are": "are",
2333
- "was": "was",
2334
- "were": "were",
2335
- "be": "be",
2336
- "but": "but",
2337
- "nor": "nor",
2338
- "so": "so",
2339
- "yet": "yet",
2340
- "per": "per",
2341
- "via": "via",
2342
- // Latin abbreviations (tokenized as words in some pipelines)
2343
- "eg": "e.g.",
2344
- "ie": "i.e.",
2345
- "etc": "etc.",
2346
- "aka": "aka",
2347
- "vs": "vs.",
2348
- "v": "v.",
2349
- // Client abbreviations
2350
- "CIC": "CIC",
2351
- "AGR": "AGR",
2352
- "AGER": "AGER",
2353
- "DD": "DD",
2354
- "TS": "TS",
2355
- "TM": "TM",
2356
- "arman": "Arman"
2357
- };
2358
- var DEFAULT_OPTIONS = {
2359
- textCase: "title",
2360
- wordReplacements: DEFAULT_WORD_REPLACEMENTS,
2361
- trim: true
2362
- };
2363
- function formatText(text, options = {}) {
2364
- const opts = { ...DEFAULT_OPTIONS, ...options };
2365
- if (!text) return "";
2366
- let normalized = text.replace(/_/g, " ").replace(/-/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ");
2367
- if (opts.trim) {
2368
- normalized = normalized.trim();
2369
- }
2370
- let caseTransformed = normalized;
2371
- switch (opts.textCase) {
2372
- case "title":
2373
- caseTransformed = normalized.replace(
2374
- /\w\S*/g,
2375
- (word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
2376
- );
2377
- break;
2378
- case "sentence":
2379
- if (normalized.length > 0) {
2380
- caseTransformed = normalized.charAt(0).toUpperCase() + normalized.slice(1).toLowerCase();
2381
- }
2382
- break;
2383
- case "lower":
2384
- caseTransformed = normalized.toLowerCase();
2385
- break;
2386
- case "upper":
2387
- caseTransformed = normalized.toUpperCase();
2388
- break;
2389
- }
2390
- let result = caseTransformed;
2391
- if (opts.wordReplacements) {
2392
- Object.entries(opts.wordReplacements).forEach(([key, value]) => {
2393
- const regex = new RegExp(`\\b${key}\\b`, "gi");
2394
- result = result.replace(regex, value);
2395
- });
2396
- }
2397
- return result;
2398
- }
2399
- var IDENTIFIER_ACRONYMS = [
2400
- "ID",
2401
- "URL",
2402
- "PDF",
2403
- "HTML",
2404
- "JSON",
2405
- "API",
2406
- "AI",
2407
- "UI",
2408
- "CSV",
2409
- "SMS",
2410
- "SEO",
2411
- "LLM",
2412
- "MCP",
2413
- "UUID",
2414
- "ISO"
2415
- ];
2416
- var IDENTIFIER_ACRONYM_SET = new Set(IDENTIFIER_ACRONYMS.map((a) => a.toLowerCase()));
2417
- function humanizeIdentifier(identifier) {
2418
- const text = (identifier ?? "").trim();
2419
- if (text === "") return "";
2420
- if (!text.includes("_") && /\s/.test(text)) {
2421
- return /^\p{Ll}/u.test(text) ? text.charAt(0).toUpperCase() + text.slice(1) : text;
2422
- }
2423
- return text.replace(/([a-z\d])([A-Z])/g, "$1 $2").replace(/([A-Z]+)(?![A-Z]s(?![a-z]))([A-Z][a-z])/g, "$1 $2").split(/[_\-.\s]+/).filter((part) => part.length > 0).map(identifierWord).join(" ");
2424
- }
2425
- function identifierWord(part) {
2426
- const lower = part.toLowerCase();
2427
- if (IDENTIFIER_ACRONYM_SET.has(lower)) return part.toUpperCase();
2428
- if (lower.length > 1 && lower.endsWith("s") && IDENTIFIER_ACRONYM_SET.has(lower.slice(0, -1))) {
2429
- return `${lower.slice(0, -1).toUpperCase()}s`;
2430
- }
2431
- return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
2432
- }
2433
-
2434
- // core/schema-structure.ts
2435
2131
  function formatBlockLabel(key) {
2436
- return formatText(key, { textCase: "title" });
2132
+ return textCase.formatText(key, { textCase: "title" });
2437
2133
  }
2438
2134
  function schemaStructureDepth(schema, allSchemas, visiting = /* @__PURE__ */ new Set()) {
2439
2135
  if (visiting.has(schema.kind)) return 0;
@@ -3296,7 +2992,7 @@ function buildAgentSchemaWithRenderBlockSupport(input, rootKindSlug, arrayBindin
3296
2992
  }
3297
2993
  function resolveRef(ref, ctx) {
3298
2994
  if (ref === "#" || ref === "#/") {
3299
- return { slug: ctx.schemaName, node: ctx.rootSchema };
2995
+ return { slug: ctx.schemaName, node: ctx.rootSchema, declaresKind: true };
3300
2996
  }
3301
2997
  const match = /^#\/(?:\$defs|definitions)\/(.+)$/.exec(ref);
3302
2998
  if (!match) return null;
@@ -3306,7 +3002,11 @@ function resolveRef(ref, ctx) {
3306
3002
  const node = ctx.defs[name];
3307
3003
  if (!isRecord4(node)) return null;
3308
3004
  const declared = isRecord4(node.properties) ? readBlockKindFromProperties(node.properties) : null;
3309
- return { slug: declared ?? name, node };
3005
+ return { slug: declared ?? name, node, declaresKind: declared !== null };
3006
+ }
3007
+ function inlineRefNode(refNode, resolved) {
3008
+ const { $ref: _ref, ...beside } = refNode;
3009
+ return { ...resolved.node, ...beside };
3310
3010
  }
3311
3011
  function refToObjectField(resolved, path, ctx) {
3312
3012
  if (ctx.refsInProgress.has(resolved.slug)) return;
@@ -3376,6 +3076,29 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3376
3076
  });
3377
3077
  return null;
3378
3078
  }
3079
+ if (!resolved.declaresKind) {
3080
+ const guard = `$def:${node.$ref}`;
3081
+ if (ctx.refsInProgress.has(guard)) {
3082
+ ctx.problems.push({
3083
+ severity: "info",
3084
+ path,
3085
+ message: `Self-referencing structure "${node.$ref}" \u2014 carried as any JSON value (json).`
3086
+ });
3087
+ return { ...requiredNullableFlags(required), type: "json" };
3088
+ }
3089
+ ctx.refsInProgress.add(guard);
3090
+ try {
3091
+ return convertPropertyCore(
3092
+ fieldName,
3093
+ inlineRefNode(node, resolved),
3094
+ required,
3095
+ path,
3096
+ ctx
3097
+ );
3098
+ } finally {
3099
+ ctx.refsInProgress.delete(guard);
3100
+ }
3101
+ }
3379
3102
  refToObjectField(resolved, path, ctx);
3380
3103
  return {
3381
3104
  ...requiredNullableFlags(required),
@@ -3407,6 +3130,10 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3407
3130
  unsupported = true;
3408
3131
  continue;
3409
3132
  }
3133
+ if (!resolvedVariant.declaresKind) {
3134
+ anonymousObjects.push(inlineRefNode(variant, resolvedVariant));
3135
+ continue;
3136
+ }
3410
3137
  refToObjectField(resolvedVariant, path, ctx);
3411
3138
  memberKinds.push(resolvedVariant.slug);
3412
3139
  continue;
@@ -5092,10 +4819,8 @@ function tryDecodeDirectiveContent(content, onError) {
5092
4819
  }
5093
4820
  return tryDecodeDirective(parsed, onError);
5094
4821
  }
5095
-
5096
- // directives/display.ts
5097
4822
  function titleCaseToken(token) {
5098
- return humanizeIdentifier(token) || token;
4823
+ return textCase.humanizeIdentifier(token) || token;
5099
4824
  }
5100
4825
  var ACTION_BY_CLASS = {
5101
4826
  reference: "Reference",
@@ -8094,6 +7819,198 @@ function resolveReferenceLinks(fragment, defs) {
8094
7819
  return resolved.replace(new RegExp(`${PLACEHOLDER}(\\d+)${PLACEHOLDER}`, "g"), (_m, i) => spans[Number(i)] ?? "");
8095
7820
  }
8096
7821
 
7822
+ // source/delimiter-guard.ts
7823
+ var ZWSP = "\u200B";
7824
+ var ESCAPED_DOLLARS = `${ZWSP}$${ZWSP}$`;
7825
+ var ESCAPED_BRACKET = `${ZWSP}[`;
7826
+ function protectedRanges(text) {
7827
+ return findCodeRanges(text).map((r) => [r.start, r.end]);
7828
+ }
7829
+ function isProtected(index, ranges) {
7830
+ return ranges.some(([start, end]) => index >= start && index < end);
7831
+ }
7832
+ function preview(text, max = 160) {
7833
+ const flat = text.replace(/\s+/g, " ").trim();
7834
+ return flat.length > max ? `${flat.slice(0, max)}\u2026` : flat;
7835
+ }
7836
+ function guardMathDelimiters(text) {
7837
+ if (!text.includes("$$")) return { text, violations: [] };
7838
+ const ranges = protectedRanges(text);
7839
+ const tokens = [];
7840
+ for (let i = 0; i < text.length - 1; i++) {
7841
+ if (text[i] !== "$" || text[i + 1] !== "$") continue;
7842
+ if (!isProtected(i, ranges)) tokens.push(i);
7843
+ i++;
7844
+ }
7845
+ if (tokens.length === 0) return { text, violations: [] };
7846
+ const violations = [];
7847
+ const escapeAt = [];
7848
+ let j = 0;
7849
+ while (j < tokens.length) {
7850
+ const open = tokens[j];
7851
+ const close = tokens[j + 1];
7852
+ if (close === void 0) {
7853
+ violations.push({
7854
+ reason: "unpaired",
7855
+ index: open,
7856
+ spanLength: 0,
7857
+ // An unpaired `$$` is inert to remark-math (nothing closes it), so it
7858
+ // is reported but NOT escaped — it already renders as literal text.
7859
+ preview: preview(text.slice(open, open + 120))
7860
+ });
7861
+ break;
7862
+ }
7863
+ const inner = text.slice(open + 2, close);
7864
+ if (isMathPlaceholder(inner)) {
7865
+ escapeAt.push(open, close);
7866
+ violations.push({ reason: "prose-span", index: open, spanLength: inner.length, preview: preview(inner) });
7867
+ j += 2;
7868
+ continue;
7869
+ }
7870
+ if (looksLikeDisplayMath(inner, opensFlowBlock(text, open))) {
7871
+ j += 2;
7872
+ continue;
7873
+ }
7874
+ escapeAt.push(open);
7875
+ violations.push({
7876
+ reason: "prose-span",
7877
+ index: open,
7878
+ spanLength: inner.length,
7879
+ preview: preview(inner)
7880
+ });
7881
+ j += 1;
7882
+ }
7883
+ let guarded = text;
7884
+ for (const index of [...escapeAt].sort((a, b) => b - a)) {
7885
+ guarded = `${guarded.slice(0, index)}${ESCAPED_DOLLARS}${guarded.slice(index + 2)}`;
7886
+ }
7887
+ return { text: guarded, violations };
7888
+ }
7889
+ var MAX_LINK_LABEL = 200;
7890
+ var LABEL_BLOCK_STRUCTURE = /\n[ \t]*\n|(?:^|\n)[ \t]*[-*+][ \t]+|#{2,6}[ \t]/;
7891
+ function guardRunawayLinks(text) {
7892
+ if (!text.includes("[")) return { text, violations: [] };
7893
+ const ranges = protectedRanges(text);
7894
+ const violations = [];
7895
+ const escapeAt = [];
7896
+ const linkRe = /\[((?:[^[\]\\]|\\.)*)\]\(([^\s)]*)/g;
7897
+ let m;
7898
+ while ((m = linkRe.exec(text)) !== null) {
7899
+ const open = m.index;
7900
+ if (isProtected(open, ranges)) continue;
7901
+ const label = m[1] ?? "";
7902
+ const runaway = label.length > MAX_LINK_LABEL || LABEL_BLOCK_STRUCTURE.test(label);
7903
+ if (!runaway) continue;
7904
+ escapeAt.push(open);
7905
+ violations.push({
7906
+ reason: "runaway-link",
7907
+ index: open,
7908
+ spanLength: label.length,
7909
+ preview: preview(label)
7910
+ });
7911
+ }
7912
+ let guarded = text;
7913
+ for (const index of [...escapeAt].sort((a, b) => b - a)) {
7914
+ guarded = `${guarded.slice(0, index)}${ESCAPED_BRACKET}${guarded.slice(index + 1)}`;
7915
+ }
7916
+ return { text: guarded, violations };
7917
+ }
7918
+ function guardMarkdownDelimiters(text) {
7919
+ const math = guardMathDelimiters(text);
7920
+ const links = guardRunawayLinks(math.text);
7921
+ return {
7922
+ text: links.text,
7923
+ violations: [...math.violations, ...links.violations]
7924
+ };
7925
+ }
7926
+ function reportDelimiterViolations(violations, context) {
7927
+ if (violations.length === 0) return;
7928
+ try {
7929
+ const worst = violations.find((v) => v.reason !== "unpaired") ?? violations[0];
7930
+ if (!worst) return;
7931
+ const message = worst.reason === "prose-span" ? `Malformed math delimiters: a stray "$$" would have turned ${worst.spanLength} chars of prose into a math span (KaTeX would render it as red error text). Escaped it.` : worst.reason === "runaway-link" ? `Runaway markdown link: an unclosed "[" would have turned ${worst.spanLength} chars into one link label. Escaped it.` : `Malformed math delimiters: an unpaired "$$" reached the renderer.`;
7932
+ console.warn(`[markdown-delimiter-guard] ${message}`, {
7933
+ renderPath: context.renderPath,
7934
+ violations
7935
+ });
7936
+ context.capture?.({
7937
+ source: "markdown-delimiters",
7938
+ message,
7939
+ relation: `markdown:${context.renderPath}`,
7940
+ details: worst.preview,
7941
+ conversationId: context.conversationId,
7942
+ callSite: "guardMarkdownDelimiters",
7943
+ raw: { messageId: context.messageId, violations }
7944
+ });
7945
+ } catch {
7946
+ }
7947
+ }
7948
+
7949
+ // source/thinking.ts
7950
+ function codeRanges2(text, live) {
7951
+ const ranges = findCodeRanges(text).map((r) => [r.start, r.end]);
7952
+ if (live) {
7953
+ const pending = pendingCodeSpanStart(text);
7954
+ if (pending >= 0 && !inCode(ranges, pending)) ranges.push([pending, text.length]);
7955
+ }
7956
+ return ranges.sort((x, y) => x[0] - y[0]);
7957
+ }
7958
+ function inCode(ranges, index) {
7959
+ return ranges.some(([a, b]) => index >= a && index < b);
7960
+ }
7961
+ function collapseGaps(text) {
7962
+ const ranges = codeRanges2(text, false);
7963
+ let out = "";
7964
+ let at = 0;
7965
+ for (const [a, b] of ranges) {
7966
+ out += text.slice(at, a).replace(/\n{3,}/g, "\n\n") + text.slice(a, b);
7967
+ at = b;
7968
+ }
7969
+ return out + text.slice(at).replace(/\n{3,}/g, "\n\n");
7970
+ }
7971
+ var OPEN_TAG = /<(thinking|reasoning)\b[^>]*>/gi;
7972
+ function removeClosedBlocks(input, live) {
7973
+ let text = input;
7974
+ for (; ; ) {
7975
+ const ranges = codeRanges2(text, live);
7976
+ OPEN_TAG.lastIndex = 0;
7977
+ let opener = null;
7978
+ for (let m = OPEN_TAG.exec(text); m; m = OPEN_TAG.exec(text)) {
7979
+ if (!inCode(ranges, m.index)) {
7980
+ opener = m;
7981
+ break;
7982
+ }
7983
+ }
7984
+ if (!opener) return { text, openAt: -1 };
7985
+ const closeTag = new RegExp(`</${opener[1]}\\s*>`, "gi");
7986
+ closeTag.lastIndex = opener.index + opener[0].length;
7987
+ let closer = null;
7988
+ for (let m = closeTag.exec(text); m; m = closeTag.exec(text)) {
7989
+ if (!inCode(ranges, m.index)) {
7990
+ closer = m;
7991
+ break;
7992
+ }
7993
+ }
7994
+ if (!closer) return { text, openAt: opener.index };
7995
+ text = text.slice(0, opener.index) + text.slice(closer.index + closer[0].length);
7996
+ }
7997
+ }
7998
+ function stripThinking(input) {
7999
+ if (!input) return "";
8000
+ return collapseGaps(removeClosedBlocks(input, false).text).trim();
8001
+ }
8002
+ function hasThinkingTags(input) {
8003
+ if (!input) return false;
8004
+ return removeClosedBlocks(input, false).text !== input;
8005
+ }
8006
+ function stripThinkingStreaming(input) {
8007
+ if (!input) return { visible: "", isThinking: false };
8008
+ const { text, openAt } = removeClosedBlocks(input, true);
8009
+ const isThinking = openAt !== -1;
8010
+ const kept = isThinking ? text.slice(0, openAt) : text;
8011
+ return { visible: collapseGaps(kept).replace(/^\s+/, ""), isThinking };
8012
+ }
8013
+
8097
8014
  // source/code-range-edits.ts
8098
8015
  function unwrapCodeSpans(text) {
8099
8016
  if (!text.includes("`")) return text;
@@ -8599,6 +8516,10 @@ exports.findWholeTableStart = findWholeTableStart;
8599
8516
  exports.fingerprintText = fingerprintText;
8600
8517
  exports.formatBlockLabel = formatBlockLabel;
8601
8518
  exports.getParseSession = getParseSession;
8519
+ exports.guardMarkdownDelimiters = guardMarkdownDelimiters;
8520
+ exports.guardMathDelimiters = guardMathDelimiters;
8521
+ exports.guardRunawayLinks = guardRunawayLinks;
8522
+ exports.hasThinkingTags = hasThinkingTags;
8602
8523
  exports.hasUnclosedBacktickRun = hasUnclosedBacktickRun;
8603
8524
  exports.indexOutsideInlineCode = indexOutsideInlineCode;
8604
8525
  exports.initialXmlBalance = initialXmlBalance;
@@ -8678,6 +8599,7 @@ exports.rehydrateNodeOutcome = rehydrateNodeOutcome;
8678
8599
  exports.rehydrateRunResult = rehydrateRunResult;
8679
8600
  exports.removeCodeSpans = removeCodeSpans;
8680
8601
  exports.replaceFences = replaceFences;
8602
+ exports.reportDelimiterViolations = reportDelimiterViolations;
8681
8603
  exports.resetLegacyShellUses = resetLegacyShellUses;
8682
8604
  exports.resolveReferenceLinks = resolveReferenceLinks;
8683
8605
  exports.resolvesInContent = resolvesInContent;
@@ -8704,6 +8626,8 @@ exports.startsPipelessTable = startsPipelessTable;
8704
8626
  exports.storageToKindSchema = storageToKindSchema;
8705
8627
  exports.stripControlKeys = stripControlKeys;
8706
8628
  exports.stripKindDeep = stripKindDeep;
8629
+ exports.stripThinking = stripThinking;
8630
+ exports.stripThinkingStreaming = stripThinkingStreaming;
8707
8631
  exports.tableContainerIndent = tableContainerIndent;
8708
8632
  exports.tableStartsAt = tableStartsAt;
8709
8633
  exports.titleCaseToken = titleCaseToken;