mirror of
https://github.com/Youzini-afk/ST-Bionic-Memory-Ecology.git
synced 2026-05-15 22:30:38 +08:00
Harden legacy extraction and recall JSON parsing
This commit is contained in:
55
retriever.js
55
retriever.js
@@ -97,6 +97,44 @@ function buildRecallFallbackReason(llmResult) {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveRecallSelectedIds(result) {
|
||||
if (Array.isArray(result)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const visited = new Set();
|
||||
const queue = [{ value: result, depth: 0 }];
|
||||
while (queue.length > 0) {
|
||||
const current = queue.shift();
|
||||
const value = current?.value;
|
||||
const depth = Number(current?.depth) || 0;
|
||||
if (!value || typeof value !== "object" || visited.has(value) || depth > 1) {
|
||||
continue;
|
||||
}
|
||||
visited.add(value);
|
||||
|
||||
const directCandidates = [
|
||||
value.selected_ids,
|
||||
value.selectedIds,
|
||||
value.node_ids,
|
||||
value.nodeIds,
|
||||
value.ids,
|
||||
];
|
||||
for (const candidate of directCandidates) {
|
||||
if (Array.isArray(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
queue.push({ value: value.data, depth: depth + 1 });
|
||||
queue.push({ value: value.result, depth: depth + 1 });
|
||||
queue.push({ value: value.payload, depth: depth + 1 });
|
||||
queue.push({ value: value.output, depth: depth + 1 });
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function isAbortError(error) {
|
||||
return error?.name === "AbortError";
|
||||
}
|
||||
@@ -1515,21 +1553,22 @@ async function llmRecall(
|
||||
returnFailureDetails: true,
|
||||
});
|
||||
const result = llmResult?.ok ? llmResult.data : null;
|
||||
const selectedIds = resolveRecallSelectedIds(result);
|
||||
|
||||
if (result?.selected_ids && Array.isArray(result.selected_ids)) {
|
||||
if (Array.isArray(selectedIds)) {
|
||||
// 校验 ID 有效性
|
||||
const validIds = uniqueNodeIds(
|
||||
result.selected_ids.filter((id) =>
|
||||
selectedIds.filter((id) =>
|
||||
candidates.some((c) => c.nodeId === id),
|
||||
),
|
||||
).slice(0, maxNodes);
|
||||
|
||||
if (validIds.length > 0 || result.selected_ids.length === 0) {
|
||||
if (validIds.length > 0 || selectedIds.length === 0) {
|
||||
return {
|
||||
selectedNodeIds: validIds,
|
||||
status: "llm",
|
||||
reason:
|
||||
validIds.length < result.selected_ids.length
|
||||
validIds.length < selectedIds.length
|
||||
? "LLM 返回了部分无效或超限 ID,已自动裁剪"
|
||||
: "LLM 精排完成",
|
||||
};
|
||||
@@ -1538,7 +1577,7 @@ async function llmRecall(
|
||||
|
||||
// LLM 失败时回退到纯评分排序
|
||||
const fallbackReason = llmResult?.ok
|
||||
? Array.isArray(result?.selected_ids)
|
||||
? Array.isArray(selectedIds)
|
||||
? "LLM 返回的候选 ID 无效,已回退到评分排序"
|
||||
: "LLM 返回了无法识别的 JSON 结构,已回退到评分排序"
|
||||
: buildRecallFallbackReason(llmResult);
|
||||
@@ -1546,7 +1585,11 @@ async function llmRecall(
|
||||
selectedNodeIds: candidates.slice(0, maxNodes).map((c) => c.nodeId),
|
||||
status: "fallback",
|
||||
reason: fallbackReason,
|
||||
fallbackType: llmResult?.ok ? "invalid-candidate" : llmResult?.errorType || "unknown",
|
||||
fallbackType: llmResult?.ok
|
||||
? Array.isArray(selectedIds)
|
||||
? "invalid-candidate"
|
||||
: "invalid-structure"
|
||||
: llmResult?.errorType || "unknown",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user