Files
openclaw/src/gateway/session-transcript-json.ts
Peter Steinberger 2aa4ff0825 refactor: consolidate duplicate helper exports (#106016)
* refactor(normalization): consolidate string helpers

* refactor(normalization): consolidate agent ids

* refactor(paths): consolidate user path resolution

* refactor(gateway): preserve transcript helper facade

* fix(normalization): align helper build aliases

* fix(memory): keep helper import line neutral

* chore(plugin-sdk): align consolidated helper surface

* refactor(normalization): reuse lowercase string helper

* refactor(normalization): reuse record guard

* refactor(normalization): share surrogate boundary helper

* refactor(agents): share token estimate constant

* refactor(memory): distinguish standalone helper contracts

* refactor(normalization): share error cause formatter

* refactor(config): distinguish eligibility predicates

* refactor(plugins): share registry state symbol

* refactor(cli): reuse outbound dependency adapter

* refactor(cron): distinguish positive duration parser

* fix(gateway): keep transcript helper private

* fix(paths): preserve public helper status

* refactor(channels): reuse registry normalizer

* refactor(agents): reuse agent core runtime facade

* refactor(auth): reuse locked profile upsert

* refactor(records): distinguish trap-safe guard

* refactor(migrations): distinguish sync directory helper

* test(plugins): drop stale duration alias expectations

* fix(channels): remove stale registry import

* chore(plugin-sdk): refresh helper API baseline

* fix(memory): keep renamed helpers private

* fix(plugins): keep registry state key private

* fix(plugin-sdk): tighten wildcard surface budget

* chore(plugin-sdk): refresh rebased helper API baseline
2026-07-13 03:22:00 -07:00

66 lines
2.2 KiB
TypeScript

// Shared bounded JSONL metadata parsing for gateway transcript readers.
import { escapeRegExp } from "../shared/regexp.js";
/** Reads a nonblank transcript field while preserving its original whitespace. */
export function readNonBlankStringPreservingWhitespace(value: unknown): string | undefined {
return typeof value === "string" && value.trim().length > 0 ? value : undefined;
}
// Transcript readers repeatedly extract a fixed set of metadata fields from
// oversized JSONL prefixes. Keep the compiled regexes process-local instead of
// rebuilding them for every field on every oversized record.
const TRANSCRIPT_FIELD_REGEX_CACHE = new Map<
string,
{ stringRe: RegExp; nullRe: RegExp; numberRe: RegExp }
>();
function getTranscriptFieldRegexes(field: string): {
stringRe: RegExp;
nullRe: RegExp;
numberRe: RegExp;
} {
let cached = TRANSCRIPT_FIELD_REGEX_CACHE.get(field);
if (!cached) {
const escapedField = escapeRegExp(field);
cached = {
stringRe: new RegExp(`"${escapedField}"\\s*:\\s*"((?:\\\\.|[^"\\\\])*)"`),
nullRe: new RegExp(`"${escapedField}"\\s*:\\s*null`),
numberRe: new RegExp(`"${escapedField}"\\s*:\\s*(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)`),
};
TRANSCRIPT_FIELD_REGEX_CACHE.set(field, cached);
}
return cached;
}
export function extractJsonStringFieldPrefix(prefix: string, field: string): string | undefined {
const match = getTranscriptFieldRegexes(field).stringRe.exec(prefix);
if (!match) {
return undefined;
}
try {
const decoded = JSON.parse(`"${match[1]}"`) as unknown;
return readNonBlankStringPreservingWhitespace(decoded);
} catch {
return undefined;
}
}
export function extractJsonNullableStringFieldPrefix(
prefix: string,
field: string,
): string | null | undefined {
if (getTranscriptFieldRegexes(field).nullRe.test(prefix)) {
return null;
}
return extractJsonStringFieldPrefix(prefix, field);
}
export function extractJsonNumberFieldPrefix(prefix: string, field: string): number | undefined {
const match = getTranscriptFieldRegexes(field).numberRe.exec(prefix);
if (!match) {
return undefined;
}
const decoded = Number(match[1]);
return Number.isFinite(decoded) ? decoded : undefined;
}