mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 05:17:40 +00:00
Memory/QMD: robustly parse noisy qmd JSON output
This commit is contained in:
@@ -25,11 +25,19 @@ export function parseQmdQueryJson(stdout: string, stderr: string): QmdQueryResul
|
||||
throw new Error(`qmd query returned invalid JSON: ${message}`);
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(trimmedStdout) as unknown;
|
||||
if (!Array.isArray(parsed)) {
|
||||
const parsed = parseQmdQueryResultArray(trimmedStdout);
|
||||
if (parsed !== null) {
|
||||
return parsed;
|
||||
}
|
||||
const noisyPayload = extractFirstJsonArray(trimmedStdout);
|
||||
if (!noisyPayload) {
|
||||
throw new Error("qmd query JSON response was not an array");
|
||||
}
|
||||
return parsed as QmdQueryResult[];
|
||||
const fallback = parseQmdQueryResultArray(noisyPayload);
|
||||
if (fallback !== null) {
|
||||
return fallback;
|
||||
}
|
||||
throw new Error("qmd query JSON response was not an array");
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err);
|
||||
log.warn(`qmd query returned invalid JSON: ${message}`);
|
||||
@@ -45,3 +53,56 @@ function isQmdNoResultsOutput(raw: string): boolean {
|
||||
function summarizeQmdStderr(raw: string): string {
|
||||
return raw.length <= 120 ? raw : `${raw.slice(0, 117)}...`;
|
||||
}
|
||||
|
||||
function parseQmdQueryResultArray(raw: string): QmdQueryResult[] | null {
|
||||
try {
|
||||
const parsed = JSON.parse(raw) as unknown;
|
||||
if (!Array.isArray(parsed)) {
|
||||
return null;
|
||||
}
|
||||
return parsed as QmdQueryResult[];
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function extractFirstJsonArray(raw: string): string | null {
|
||||
const start = raw.indexOf("[");
|
||||
if (start < 0) {
|
||||
return null;
|
||||
}
|
||||
let depth = 0;
|
||||
let inString = false;
|
||||
let escaped = false;
|
||||
for (let i = start; i < raw.length; i += 1) {
|
||||
const char = raw[i];
|
||||
if (char === undefined) {
|
||||
break;
|
||||
}
|
||||
if (inString) {
|
||||
if (escaped) {
|
||||
escaped = false;
|
||||
continue;
|
||||
}
|
||||
if (char === "\\") {
|
||||
escaped = true;
|
||||
} else if (char === '"') {
|
||||
inString = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (char === '"') {
|
||||
inString = true;
|
||||
continue;
|
||||
}
|
||||
if (char === "[") {
|
||||
depth += 1;
|
||||
} else if (char === "]") {
|
||||
depth -= 1;
|
||||
if (depth === 0) {
|
||||
return raw.slice(start, i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user