openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
123 lines (122 loc) • 5.42 kB
JavaScript
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { c as hasInternalRuntimeContext, m as stripInternalRuntimeContext } from "./internal-runtime-context-UgZVJlox.js";
import { S as isLegacyCodexProviderId } from "./codex-route-model-ref-Br4ltBF-.js";
import { a as mergeSessionTranscriptVisiblePathWithOpaqueAppendPath, c as scanSessionTranscriptTree, d as selectSessionTranscriptTreePathNodes, i as mergeSessionTranscriptTreePaths, n as isSessionTranscriptLeafControl } from "./transcript-tree-BH69pMSi.js";
//#region src/config/sessions/legacy-transcript-repair.ts
/** Pure legacy transcript repair shared by standalone Doctor and its import spool. */
const OPENAI_PROVIDER_ID = "openai";
const LEGACY_OPENAI_CODEX_RESPONSES_API = "openai-codex-responses";
const OPENAI_CHATGPT_RESPONSES_API = "openai-chatgpt-responses";
function getEntryId(entry) {
return typeof entry.id === "string" && entry.id.trim() ? entry.id : null;
}
function getParentId(entry) {
return typeof entry.parentId === "string" && entry.parentId.trim() ? entry.parentId : null;
}
function getMessage(entry) {
return isRecord(entry.message) ? entry.message : null;
}
function withSelectedParent(entry, parentId) {
return entry.parentId === parentId ? entry : {
...entry,
parentId
};
}
function normalizeLegacyOpenAICodexTranscriptMetadata(entries) {
let changed = 0;
for (const entry of entries) {
const message = getMessage(entry);
if (!message) continue;
let touched = false;
if (isLegacyCodexProviderId(message.provider)) {
message.provider = OPENAI_PROVIDER_ID;
touched = true;
}
if (message.api === LEGACY_OPENAI_CODEX_RESPONSES_API) {
message.api = OPENAI_CHATGPT_RESPONSES_API;
touched = true;
}
if (touched) changed += 1;
}
return changed;
}
function textFromContent(content) {
if (typeof content === "string") return content;
if (!Array.isArray(content)) return null;
return content.map((part) => isRecord(part) && typeof part.text === "string" ? part.text : "").join("") || null;
}
function selectActivePath(entries) {
const sessionEntries = entries.filter((entry) => entry.type !== "session");
const tree = scanSessionTranscriptTree(sessionEntries);
if (!tree.hasExplicitLeafUpdate) {
const byId = /* @__PURE__ */ new Map();
for (const entry of sessionEntries) {
const id = getEntryId(entry);
if (id) byId.set(id, entry);
}
const active = [];
const seen = /* @__PURE__ */ new Set();
let current = sessionEntries.at(-1);
while (current) {
const id = getEntryId(current);
if (!id || seen.has(id)) return null;
seen.add(id);
active.unshift(current);
const parentId = getParentId(current);
current = parentId ? byId.get(parentId) : void 0;
}
return active.length > 0 ? {
entries: active,
entriesToPersist: active,
terminalLeafControl: null,
appendParentId: getEntryId(active.at(-1) ?? {})
} : null;
}
if (!tree.hasLeafUpdate) return null;
const visiblePath = selectSessionTranscriptTreePathNodes(tree, tree.leafId);
const appendPath = selectSessionTranscriptTreePathNodes(tree, tree.appendParentId);
const visibleEntries = mergeSessionTranscriptTreePaths([visiblePath]).map((node) => withSelectedParent(node.entry, node.selectedParentId));
const persistedPath = mergeSessionTranscriptVisiblePathWithOpaqueAppendPath({
visiblePath,
appendPath,
appendParentId: tree.appendParentId
});
const entriesToPersist = persistedPath.nodes.map((node) => withSelectedParent(node.entry, node.selectedParentId));
const lastLeafUpdateEntry = tree.nodes.findLast((node) => node.leafId !== void 0)?.entry;
return {
entries: visibleEntries,
entriesToPersist,
terminalLeafControl: isSessionTranscriptLeafControl(lastLeafUpdateEntry) ? lastLeafUpdateEntry : null,
appendParentId: persistedPath.appendParentId
};
}
function hasBrokenPromptRewriteBranch(entries, activePath) {
const activeIds = new Set(activePath.map(getEntryId).filter((id) => Boolean(id)));
const keys = new Set(activePath.map((entry) => transcriptRepairUserKey(entry, false)).filter((key) => key !== void 0));
return entries.some((entry) => !activeIds.has(getEntryId(entry) ?? "") && keys.has(transcriptRepairUserKey(entry, true) ?? ""));
}
function selectActiveTranscriptEntries(params) {
const header = params.entries.find((entry) => entry.type === "session");
if (!header) throw new Error("missing session header");
const lastPersistedId = getEntryId(params.activePath.entriesToPersist.at(-1) ?? {});
const terminalLeafControl = params.activePath.terminalLeafControl ? {
...params.activePath.terminalLeafControl,
parentId: lastPersistedId,
appendParentId: params.activePath.appendParentId
} : null;
return [
header,
...params.activePath.entriesToPersist,
...terminalLeafControl ? [terminalLeafControl] : []
];
}
function transcriptRepairUserKey(entry, strip) {
const message = getMessage(entry);
if (!getEntryId(entry) || message?.role !== "user") return;
const text = textFromContent(message.content);
if (text === null || strip && !hasInternalRuntimeContext(text)) return;
const visible = (strip ? stripInternalRuntimeContext(text) : text).trim();
return visible ? `${getParentId(entry) ?? ""}\0${visible}` : void 0;
}
//#endregion
export { transcriptRepairUserKey as a, selectActiveTranscriptEntries as i, normalizeLegacyOpenAICodexTranscriptMetadata as n, selectActivePath as r, hasBrokenPromptRewriteBranch as t };